help with blending + masks

I’m trying to wrap my head around what the blend command is doing… or what it’s not doing :P.

I’ve used it before to ‘mix’ two images together, using the opacity parameter to specify how much of each image to use.

blend[0,1] alpha, 0%		# Use only the first image
blend[0,1] alpha,33%		# Use 33% image 0, 66% image 1
blend[0,1] alpha,50%		# mix images together 50/50
blend[0,1] alpha,100%		# use only image two

Am I even correct in thinking that’s what’s happening? Results seem to be OK but I didn’t check really if it matches up with my expectation.

Now, here is where I don’t understand how to do something.

I have an image, it is in 0.0 - 1.0 scale (linear gamma if it matters).

I want to blend a certain color, but with an (alpha) mask.

# 0 is my image (3 channels, RGB), 1 is my image filled with a certain color (3 channels, RGB), 2 is my single-channel mask (gray)
append[1,2] c to_rgba.		# append mask-channel to image 1, so it now has 4 channels (RGBA)

# 0 is my image (3 channels, RGB), 1 is my color-image with 4th alpha channel
blend[0,1] alpha,100%

# I now expect to have a single image: my source image with the color drawn on top, but using
# the opacity from the mask channel I started with

But I keep ending up with no blend happening at all.

I then thought 'maybe because my source image is RGB and not RGBA. So I made sure it had an alpha channel filled with 1.0 (as in, completely opaque).

Now when I use ‘display’ I see something is blending. It seems to add all channels together, because I end up with an alpha channel in the range 0.0 - 2.0, and every pixel in my source image seems to be affected (the same amount) by the color from the color-image. But this is not what I was expecting :).

(Something about expectation vs reality on my side here :)).

So, how to do something that seems very simple in most photo editors:
I have a source image (bottom layer, ‘background layer’). I create a new layer on top filled with a certain color, and apply a mask / opacity (non-binary to be clear) to that new layer on top.

And then, how to do that with non-normal blend modes (like ‘multiple’, ‘soft light’ or what I was really hoping for: ‘reflect’… hoping it’s the same as Reflect in Affinity Photo’s blending modes).

I thinks this is the cause of the issue.
The blend command assumes that RGB values are in [0,255] (float-valued), not [0,1].
So an opacity channel filled with 1.0 means “almost completely transparent”.

Try multiplying everything by 255 before using blend
(you can still divide the result by 255 afterwards if needed).

You are my hero!

Still can’t my wrap around assuming a 0 - 255 range, apparently :slight_smile:.

Working with 16bit integer images, I expect 0 - 65535, or because it are floating-point numbers I expect 0.0 - 1.0 (or under/above for HDR stuff).

I tried doing the thing I wanted to do with Imagemagick, but it didn’t do the same as in Affinity Photo. I think I got stuck in image-order limbo, or weird sRGB vs RGB behaviour in certain Imagemagick situations.

But the moment I put a mul[0,1] 255 and div. 255 around the blend, it worked and also instantly did what I was hoping it would do. Awesome!

Now, is there a way for a gmic-qt / gmic-gimp filter to output numbers somewhere? I have a filter that autodetects some things (and I make use of the preview and sliders and such), but once I’m happy with something I echo numbers in the gmic-commands. Those numbers I can give to another film that then is able to batch-process images.

But ‘echo’ is not doing much inside of gmic-qt :).
There must be some way for debugging filters, to see the echo-output somewhere right? On the CLI it’s easy, but sometimes I want to debug inside of gmic-qt…

1 Like

echo works in a gmic-qt filter, you just have to be sure the verbosity level is high enough (typically >0).
so, just add v 1 before your echo[] and it should be OK (it will display its content on stderr).

Also, you can use +echo[] to output text on stdout instead.

Finally, it may be useful to output a text file as well. In that case, using a variable to store text content can be done as well:

out=
repeat 10
  out.={u(0,100)}"\n"  # Append a new line to the variable content
done
('$out') output_text. logfile remove.

With no console window, echo’ing to stdout or stderr isn’t really doing anything. And I haven’t found the logfile yet where the ‘verbose (logfile)’ logfile is written to.

I’ll use your ‘write to textfile’ or just do a 2nd pass on the gmic cli I guess. Thanks!

The log is written in %APPDATA%/gmic/gmic_qt_log.