Request for various Pegtop Blending Modes addition

Questions and postings pertaining to the development of ImageMagick, feature enhancements, and ImageMagick internals. ImageMagick source code and algorithms are discussed here. Usage questions which are too arcane for the normal user list should also be posted here.
Locked
andersz
Posts: 5
Joined: 2020-02-29T03:21:07-07:00
Authentication code: 1152

Request for various Pegtop Blending Modes addition

Post by andersz »

I decided to ask if the various blend modes on the linked page url could be implemented in ImageMagick as I see several in it that are not available and seem very useful and seeing ImageMagick is like the swiss knife tool to go to, I think this would be excellent diversity addition to add to its existing blending features.

http://www.pegtop.net/delphi/articles/blendmodes/

Modes of potential Interest:

Negation mode (under difference modes list)

Description:
This one is the "opposite" of difference mode. Note that it is NOT difference mode inverted, because black and white return the same result, but colors between become brighter instead of darker. This mode can be used to invert parts of the base image, but NOT to compare two images. An interesting note: Unlike XOR mode, this mode (generally) cannot be undone by applying it twice, but applying it three times, you get the same result as applying it once (and so on). Since I didn't see this "forgotten" mode somewhere else, I gave it this (not that perfect) name.

Formula:
f(a,b) = 1 - |1 - a - b|

result := 255 - abs(255-a-b);

Soft Dodge mode (under dodge modes list)

Description:
This mode is a combination of color dodge and inverse color burn mode, but a lot smoother than both of them. The base image is darkened a bit, but very bright blend colors are "dodged" in. I chose this name, because my aim was to make the color dodge mode softer.

Formula:
f(a,b) = ½a / (1 - b) (for a + b < 1)
1 - ½(1 - b) / a (else)

if a + b < 256 then begin
if b = 255 then
result := 255
else begin
c := (a SHL 7) DIV (255-b);
if c > 255 then result := 255 else result := c;
end;
end
else begin
// a cannot be zero here
c := 255 - (((255-b) SHL 7) DIV a);
if c < 0 then result := 0 else result := c;
end;

Soft Burn mode (under burn modes list)

Description:
This mode is a combination of color burn and inverse color dodge mode, but a lot smoother than both of them. The base image is lightened a bit, but very dark blend colors are "burned" in. I chose this name, because my aim was to make the color burn mode softer.

Formula:
f(a,b) = ½b / (1 - a) (for a + b < 1)
1 - ½(1 - a) / b (else)

if a+b < 256 then begin
if a = 255 then
Result := 255
else begin
c := (b SHL 7) DIV (255-a);
if c > 255 then Result := 255 else Result := c;
end;
end
else begin
// b cannot be zero here
c := 255-(((255-a) SHL 7) DIV b);
if c < 0 then Result := 0 else Result := c;
end;

Reflect mode (under quadratic modes list)

Description:
This mode is useful when adding shining objects or light zones to images. The formula is similar to color dodge, but the result is not that bright in most cases. The result looks a bit like soft light.

Formula:
f(a,b) = a^2 / (1 - b)

if b = 255 then
result := 255
else begin
c := a*a DIV (255-b);
if c > 255 then result := 255 else result := c;
end;

Freeze mode (under quadratic modes list)

Description:
Another variation of reflect mode (base and blend color inverted, the result inverted again).

Formula:
f(a,b) = 1 - (1 - a)^2 / b

if b = 0 then
result := 0
else begin
c := 255 - sqr(255-a) DIV b;
if c < 0 then result := 0 else result := c;
end;

Stamp mode (under additive modes list)

Description:
This mode somehow is similar to average mode. It is helpful when applying relief or bump textures to images

Formula:
f(a,b) = a + 2*b - 1

c := a + 2*b - 256;
if c < 0 then
result := 0
else if c > 255 then
result := 255
else
result := c;

Interpolation mode

Description:
This mode somehow combines multiply and screen mode (looks very similar for very dark or bright colors). A cosine function is used for calculation, similar to a cosine interpolation algorithm (that's why I gave it this name). This result is similar to average mode, but has a better contrast.

Formula:
f(a,b) = ½ - ¼cos(pi*a) - ¼cos(pi*b)

// for i := 0 to 255 do CosineTab := Round(64-Cos(i*Pi/255)*64);
c := CosineTab + CosineTab[a];
if c > 255 then result := 255 else result := c;

Admittedly there is more but many of them are just reversing of the image order like variants but I leave it up to developers to consider which others might be useful.
Last edited by andersz on 2020-03-03T08:05:31-07:00, edited 1 time in total.

User avatar
magick
Site Admin
Posts: 11254
Joined: 2003-05-31T11:32:55-07:00

Re: Request for various Pegtop Blending Modes addition

Post by magick »

We'll add support within the next few days. Feel free to download 7.0.9-28 Beta (when its available) and verify they are working as expected.

andersz
Posts: 5
Joined: 2020-02-29T03:21:07-07:00
Authentication code: 1152

Re: Request for various Pegtop Blending Modes addition

Post by andersz »

Reflect mode test:
Source:

Image

Intended result like from G'mic:

Image

IM result:

Image

So not working as intended,

reflect mode code extra info from the page:
if b = 255 then
result := 255
else begin
c := a*a DIV (255-b);
if c > 255 then result := 255 else result := c;
end;

and the gmic's source for it reads uses squareroot and [1] etc are image numbers but yeah its hard to read unfortunately.

_blend_reflect :
-[1] 255.1 *[1] -1 +sqr[0] /[2] [1] rm[1] c[1] 0,255

thus the "2" in freeze & reflect formulas are exponents..I will amend the source codes as it was copypaste mistake from the page and assumed will check the page to confirm :/

Reflect & Freeze mode need a same fix.

Working blends: Interpolate, Stamp, SoftBurn, SoftDodge, Negate

User avatar
magick
Site Admin
Posts: 11254
Joined: 2003-05-31T11:32:55-07:00

Re: Request for various Pegtop Blending Modes addition

Post by magick »

We have a patch to fix the problem you reported. The 7.0.10-0 Beta release, with the patch, is building now.

andersz
Posts: 5
Joined: 2020-02-29T03:21:07-07:00
Authentication code: 1152

Re: Request for various Pegtop Blending Modes addition

Post by andersz »

Well, I tried it before but saw no change to result, ah Reflect mode is declared twice but changing whether its SCA or SA...
current:

case ReflectCompositeOp:
{
pixel=QuantumRange*(2.0*Sca*PerceptibleReciprocal(1.0-Dca));
break;

my understanding for a fix:

case ReflectCompositeOp:
{
pixel=QuantumRange*(Sa*Sa*PerceptibleReciprocal(1.0-Da));
break;

as I don't see ^ used in IM code and Freeze is same fix for 2.0 value

case FreezeCompositeOp:
{
pixel=QuantumRange*(1.0-(1.0-Sa*1.0-Sa)*PerceptibleReciprocal(Da));
break;

I would assume that work for freeze unless it needs it like (1.0-Sa)*(1.0-Sa)

The Sca or Sa thing I'm a bit unsure on as Gmic for example by default assume alpha is opaque in blend always even when it is not when it does the change so not likely multiplying alpha vs RGB like sca would do. this is gonna need some testing regards alpha acting.

User avatar
magick
Site Admin
Posts: 11254
Joined: 2003-05-31T11:32:55-07:00

Re: Request for various Pegtop Blending Modes addition

Post by magick »

Added a patch as you suggested. New beta binaries building now. Download and test. Let us know if further changes are needed.

andersz
Posts: 5
Joined: 2020-02-29T03:21:07-07:00
Authentication code: 1152

Re: Request for various Pegtop Blending Modes addition

Post by andersz »

RGB sourced blending with Freeze and Reflect now working as expected so main formula is correct now on all blend modes, however while reflect seems to almost match RGBA vs gmic, the freeze blend with RGBA sources causes huge erasure in RGB channel and alpha channel on the semitransparent pixels area.

thus I think the change is needed to be Sa/Da to Sca/Dca to deal with alpha properly and avoid the heavier cuts(?)

case FreezeCompositeOp:
{
pixel=QuantumRange*(1.0-(1.0-Sca)*(1.0-Sca)*
PerceptibleReciprocal(Dca));
break;

NOTE! ReflectCompositeOp: is declared TWICE in composite.c so remove the duplicate and use Sca/Dca one which i assume got used in my test being its last in list
Instead of using Sa/Da

anyway a test on RGBA png using freeze blend in IM vs Gmic is following
Source png:
Image

ImageMagick Result:

Image

Expected result like Gmic

Image

What can be figured out from Gmic version in closer study, it left alpha channel entirely unchanged it seems and the semitransparent pixels colors in RGB channels are not changed seemingly much and only the opaque area was processed by the blend formula.

I managed to make IM blend reflect close to same like affect mostlyopaque area by doing
magick ( source.png -alpha opaque ) ( source-png -alpha opaque ) -compose reflect -composite source.png -compose copyopacity -composite result.png

however with freeze this not work at all as still cuts heavily probably due to Sa/Da instead of Sca/Dca.

I'm not entirely sure how one would limit IM to just process opaque pixels only by blend mode and thus -alpha opaque was just closest guess that is close.

I need to check the other blends more with alpha reaction in mind as this thing is only thing still off else modes are perfected, I would perfect it by trying myself but not familiar of compiling IM so sorry this keeps going back and forth.

User avatar
magick
Site Admin
Posts: 11254
Joined: 2003-05-31T11:32:55-07:00

Re: Request for various Pegtop Blending Modes addition

Post by magick »

Our implementation matches the algorithm proposed @ http://www.pegtop.net/delphi/articles/b ... dratic.htm. Freeze is a close analog to Reflect and you suggest Reflect is working-- which in turn suggests Freeze is behaving properly-- unless the algorithm is not correct on the page. We could replicate your command-line for Freeze but there is no proof that is the correct solution for the Freeze blend. The CSS documentation has explicit formula for handling channels including alpha. We need the same for Freeze. Rather than add a hack to ImageMagick, we'll wait for guidance on how to properly handle the color and alpha channels for the Freeze blend.

andersz
Posts: 5
Joined: 2020-02-29T03:21:07-07:00
Authentication code: 1152

Re: Request for various Pegtop Blending Modes addition

Post by andersz »

Alright, having spent last few days looking at this in depth, the difference comes from G'mic's different handling of alpha globally in it for every blending mode (not just freeze) as the actual freeze blend mode formula works much the same if you used RGB input in Gmic.

I was not suggesting the alpha opaque trick as any implemented method (it is bad), it actually not even work for freeze while seemed help with reflect a bit, was just dead end experiment I decided to share in trying find out issue further incase someone else had better ideas.

Freeze tests and the outputs of the RGB channel after RGBA blend, alpha is toggled off in these for better viewing.
Source original RGB channel:
Image

Gmic result in RGB channel when given RGBA input and by default Gmic states Opacity=1 for both layers:
Image

Imagemagick result for RGB channel is the same whether use RGB or RGBA input and the semitransparent edge pixels vanished to pure black:

Image

I found out a sorta bypass in IM for myself personally (again this is not a suggestion for a fix but just all I could come up by existing means example ) by using write-mask (use alpha channel as it so changes mostly limited to opaque areas) when composing but regrettably Gmic sourcecode is over me to try comprehend how they do their alpha blending as it definitely deviates from the standard that ImageMagick and other software use and is thus IMO not as key thing to try pursue perfectly I think.

Write-mask with freeze RGB result in ImageMagick, closest to Gmic result:
Image

Anyway the Gmic alpha blending method likely comes from GIMP that applies same thinking of 100% opacity for both layers blend thus this thread came up on my searches that mention gamma correcting being applied but this is just a guess on my part, can't go further.

http://gimpchat.com/viewtopic.php?f=8&t=8405

Closing point, Freeze blending formula itself is all correct in my tests and vs pegtop page and difference is only due to Gmic employing different than standard alpha handling somewhat and I'm personally content having got these implemented as is.

Just for sake of research completeness Gmic formula for freeze is

_blend_freeze :
*[1] -255 -[1] 0.1 +-[0] 255 sqr[2] /[2] [1] rm[1] +[1] 1 *[1] 255 c[1] 0,255

Locked