In my quest to add alpha capacity to my image blending tools in Matlab, I've come across a bit of a snag. Among others, I've been using these links as my references as to how foreground and background alpha plays into the composition of both the output color data and output alpha.
My original approach was to simply use a a Src-Over composition for "normal" blend mode and Src-Atop composition for other modes. When compared to the output from GIMP, this produced similar, but differing results. The output alpha matches, but the RGB data differs.
Specifically, the foreground's color influence over the background is zero where the background alpha is zero. After spending a few hours looking naively through the GIMP 2.8.10 source, I notice a few things that confuse me.
Barring certain modes and a few ancillary things that happen during export that I haven't gleaned in the code yet, the approach is approximately thus:
if ~normalmode
FGalpha = min(FGalpha, BGalpha); % << why this?
end
FGalpha = FGalpha * mask * opacity;
OUTalpha = BGalpha + (1 - BGalpha) * FGalpha;
ratio = FGalpha / (OUTalpha + eps);
OUT = OUT * ratio + BG * (1 - ratio);
if normalmode
OUT = cat(3, OUT, OUTalpha);
else
OUT = cat(3, OUT, BGalpha);
end
The points of curiosity lie in the fact that I don't understand conceptually why one would take the minimum of layer alphas for composition. Certainly, this approach produces results which match GIMP, but I'm uncomfortable establishing this as a default behavior if I don't understand the reasoning.
This may be best asked of a GIMP forum somewhere, but I figured it would be more fruitful to approach a general audience. To clarify and summarize:
- Does it make sense that colors in a transparent BG region are unaffected by multiplication with an opaque foreground color? Wouldn't this risk causing bleeding of unaltered data near hard mask edges with some future operation?
- Although I haven't found anything, are there other applications out there that use this approach?
Am I wrong to use GIMP's behavior as a reference? I don't have PS to compare against, and ImageMagick is so flexible that it doesn't really suggest a particular expected behavior. Certainly, GIMP has some things it does incorrectly; maybe this is something else that may change.
EDIT: I can at least answer the last question by obviating it. I've decided to add support for both SVG 1.2 and legacy GIMP methods. The GEGL methods to be used by GIMP in the future follow the SVG methods, so I figure that suggests the propriety of the legacy methods.
For what it's worth, the SVG methods are all based on a Porter-Duff Src-Over composition. If referring to the documentation, the fact that the blend math is the same gets obfuscated because the blend and composition are algebraically combined using premultiplied alpha to reduce the overall computational cost. With the exception of SoftLight, the core blend math is the same as those used by GIMP and elsewhere.
Any other blend operation (e.g. PinLight, Hue) can be made compatible by just doing:
As = Sa * (1 - Da);
Ad = Da * (1 - Sa);
Ab = Sa * Da;
Ra = As + Ad + Ab; % output alpha
Rc = ( f(Sc,Dc)*Ab + Sc*As + Dc*Ad ) / Ra;
and then doing some algebra if you want to simplify it.