PixInsight Forum
PixInsight => General => Offtopic => Topic started by: Niall Saunders on 2010 September 30 23:53:57

Elsewhere on this section of the Forum (http://pixinsight.com/forum/index.php?topic=2381.15 (http://pixinsight.com/forum/index.php?topic=2381.15)), Rogelio explained what the equivalent PixMath expression would be to achieve a 'Screen Blend' as used in PhotoShop.
What I just wondered is, for the sake of 'compatibility', does anybody know of similar expressions for the various other blending modes used by PS? (I am not promoting or advocating their use, I am simply curious because some of them  typically for PS  have been named so obscurely that it is very difficult to imagine what is going on 'behind the screens')
Any takers?

Hmmm. I have not seen a description of the other, more obscure methods. Since The Gimp implements almost every one of them, I suppose that it should be better documented on their manual ;)

Some time ago I had researched the matter, and I found this link helpful:
http://dunnbypaul.net/blends/ (http://dunnbypaul.net/blends/)
Regards,
Enzo.

Exercise: write optimized PixelMath expressions for all of those 'blending modes'. :)

Actually it would be nice to add some preset expressions to pixel math.
My memory is getting old.
Max

Hey Enzo, that was a great link :) The PM expressions are almost ready :D

Exercise: write optimized PixelMath expressions for all of those 'blending modes'. :)
I like the idea :)
Vivid Light don't work like the image example. Edited: used a formula from this resource (http://oglop.spaces.live.com/blog/cns!FFF33B1F18C7ACFF!596.entry), works fine.
Soft Light works, but slightly different (marked on red).
Darken
Min( IMG1, IMG2 )
Multiply
IMG1 * IMG2
Color Burn (noncommutative)
1  ( 1  IMG1 ) / IMG2
Linear Burn
IMG1 + IMG2  1
Lighten
Max( IMG1, IMG2 )
Screen
1  ( 1  IMG1 ) * ( 1  IMG2 )
Color Dodge (noncommutative)
IMG1 / ( 1  IMG2 )
Overlay (noncommutative)
iif( IMG1 > 0.5, 1  ( ( 1  2 * ( IMG1  0.5 ) ) * ( 1  IMG2 ) ), ( 2 * IMG1 ) * IMG2 )
Soft Light (?) (noncommutative)
iif( IMG2 > 0.5, 1  ( 1  IMG1 ) * ( 1  ( IMG2  0.5 ) ), IMG1 * ( IMG2 + 0.5 ) )
Hard Light (noncommutative)
iif( IMG2 > 0.5, 1  ( 1  IMG1 ) * ( 1  2 * ( IMG2  0.5 ) ), IMG1 * ( 2 * IMG2 ) )
Hard Mix
iif( IMG1 < 1  IMG2, 0, 1 )
Vivid Light (noncommutative)
iif( IMG2 <= 0.5, 1  ( 1  IMG1 ) / ( 2 * ( IMG2 ) ), IMG1 / ( 2 * ( 1  IMG2 ) ) )
Linear Light (noncommutative)
iif( IMG2 > 0.5, IMG1 + 2 * ( IMG2  0.5 ), IMG1 + 2 * IMG2  1 )
Pin Light (noncommutative)
iif( IMG2 > 0.5, Max( IMG1, 2 * ( IMG2  0.5 ) ), Min( IMG1, 2 * IMG2 ) )
Difference
Abs( IMG1  IMG2 )
or else (thanks to Carlos Milovic)
IMG1  IMG2
Exclusion
0.5  2 * ( IMG1  0.5 ) * ( IMG2  0.5 )

For Difference, you may use the "" operator.

Just my humble opinion, but it would be realy awesome if pixel math would be simpler to use, instead of having to write those expressions every time, and remember them ;D

For Difference, you may use the "" operator.
Efficient :) I added this to the list.

Hi Emanuele
If you open the equation editor, there are lists of the functions and the operators... This helps a lot to build the expressions.
BTW, perhaps Juan should include a simplified PixelMath, like the one we had on the LE release... what do you think?

Thanks Carlos: Yes, I have seen the operator expression in PixelMath, but it's the logic between images that is a bit hard to come up with.
Simplified PixelMath sounds sweeeeeeeeeeeet!

Well done Enzo. 1 x is the inverse of x. PixelMath provides the pixel inversion operator ~, namely:
~x = 1  x
Knowing this you can simplify many of the expressions, and hence make them run faster. The whole set would be:
Darken
Min( IMG1, IMG2 )
Multiply
IMG1 * IMG2
Color Burn (noncommutative)
~(~IMG1/ IMG2)
Linear Burn
IMG1 + IMG2  1
Lighten
Max( IMG1, IMG2 )
Screen
~(~IMG1 * ~IMG2)
Color Dodge (noncommutative)
IMG1 / ~IMG2
Overlay (noncommutative)
iif( IMG1 > 0.5, ~(~(2*(IMG1  0.5)) * ~IMG2), 2*IMG1*IMG2 )
Soft Light (?) (noncommutative)
iif( IMG2 > 0.5, ~(~IMG1 * ~(IMG2  0.5)), IMG1*(IMG2 + 0.5) )
Hard Light (noncommutative)
iif( IMG2 > 0.5, ~(~IMG1 * ~(2*(IMG2  0.5))), 2*IMG1*IMG2 ) )
Vivid Light (??) (noncommutative)
iif( IMG2 > 0.5, ~(~IMG1/(IMG2  0.5)/2), IMG1/~(2*IMG2) )
Linear Light (noncommutative)
iif( IMG2 > 0.5, IMG1 + 2*(IMG2  0.5), IMG1 + 2*IMG2  1 )
Pin Light (noncommutative)
iif( IMG2 > 0.5, Max( IMG1, 2*(IMG2  0.5) ), Min( IMG1, 2*IMG2 ) )
Difference
IMG1  IMG2
Exclusion
0.5  2*(IMG1  0.5)*(IMG2  0.5)

Knowing this you can simplify many of the expressions, and hence make them run faster.
Ahh, the Jedi Masters always see a little further. :D Cool.
I updated the Vivid Light with a new formula that worked, and added a screenshot with all the examples created.
Best,
Enzo.

It would be great to have these as preset formulas somehow in Pixel math.
Just select the target images etc
Max

Or even some presaved process icons calling those formula for each screen blend?
Don't know how you'd reference the 2 images though? (you could drag icon on to the target image, but not sure how you'd link back to the first image?)

Good idea.
Max

I have never looked into The Gimp  I never saw a need, not as a PI user. Somebody might have some 'inside knowledge' though . . .

Or even some presaved process icons calling those formula for each screen blend?
Don't know how you'd reference the 2 images though? (you could drag icon on to the target image, but not sure how you'd link back to the first image?)
You can define a target image by replacing IMG1 (or IMG2) by $T, but the other image must be set manually by ID (to my knowledge...). I think it may be practical alternative have a simple script that allows to select the two images and the type of operation. (And if this writen by a advanced PJSR guru, might be with a preview ;) )
Enzo.

Well, thanks to Rogelio for making me 'wonder'  the end result has been simply fantastic  thanks to everyone for the hard work!!
It looks as if another PS 'barrier' can be pushed to one side, even though a little bit of 'tidyingup' might be needed. With these code snippets in place, the notion of 'Layers' draws a step closer ::)
I'm glad I asked the question now :)