Imitate Photoshop Blend Effects Like Multiply, Overlay etc

How to reproduce Photoshop's multiply blending in OpenCV?

I managed to sort this out. Feel free to comment with any suggested improvements.

First, I found a clue as to how to implement the multiply function in this post:

multiply blending

And here's a quick OpenCV implementation in C++.

Mat MultiplyBlend(const Mat& cvSource, const Mat& cvBackground) {

// assumption: cvSource and cvBackground are of type CV_8UC4

// formula: (cvSource.rgb * cvBackground.rgb * cvSource.a) + (cvBackground.rgb * (1-cvSource.a))
Mat cvAlpha(cvSource.size(), CV_8UC3, Scalar::all(0));
Mat input[] = { cvSource };
int from_to[] = { 3,0, 3,1, 3,2 };
mixChannels(input, 1, &cvAlpha, 1, from_to, 3);

Mat cvBackgroundCopy;
Mat cvSourceCopy;
cvtColor(cvSource, cvSourceCopy, CV_RGBA2RGB);
cvtColor(cvBackground, cvBackgroundCopy, CV_RGBA2RGB);

// A = cvSource.rgb * cvBackground.rgb * cvSource.a
Mat cvBlendResultLeft;
multiply(cvSourceCopy, cvBackgroundCopy, cvBlendResultLeft, 1.0 / 255.0);
multiply(cvBlendResultLeft, cvAlpha, cvBlendResultLeft, 1.0 / 255.0);
delete(cvSourceCopy);

// invert alpha
bitwise_not(cvAlpha, cvAlpha);

// B = cvBackground.rgb * (1-cvSource.a)
Mat cvBlendResultRight;
multiply(cvBackgroundCopy, cvAlpha, cvBlendResultRight, 1.0 / 255.0);
delete(cvBackgroundCopy, cvAlpha);

// A + B
Mat cvBlendResult;
add(cvBlendResultLeft, cvBlendResultRight, cvBlendResult);
delete(cvBlendResultLeft, cvBlendResultRight);

cvtColor(cvBlendResult, cvBlendResult, CV_RGB2RGBA);

return cvBlendResult;
}

Photoshop blending mode to OpenGL ES without shaders

Most photoshop blend-modes are based upon the Porter-Duff blendmodes.

These requires that all your images (textures, renderbuffer) are in premultiplied color-space. This is usually done by multiplying all pixel-values with the alpha-value before storing them in a texture. E.g. a full transparent pixel will look like black in non-premultiplied color space. If you're unfamiliar with this color-space spend an hour or two reading about it on the web. It's a neat and good concept and required for photoshop-like compositions.

Anyway - once you have your images in that format you can enable SCREEN using:

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR)

The full MULTIPLY mode is not possible with the OpenGL|ES pipeline. If you only work with full opaque pixels you can fake it using:

glBlendFunc(GL_ZERO, GL_SRC_COLOR)

The results for transparent pixels either in your texture and your framebuffer will be wrong though.

OpenGL ES 1.0 Photoshop Overlay Blend On Opaque Texture For Android

My thought is probably not.

Photoshop defines the Overlay formula as:

Multiplies or screens the colors, depending on the base color. Patterns or colors overlay the existing pixels while preserving the highlights and shadows of the base color. The base color is not replaced but is mixed with the blend color to reflect the lightness or darkness of the original color.

So what you've really got here is two separate blend modes (multiply and screen), being chosen based on the base layer color. I'm not aware of any way to dynamically switch blend modes based on the base layer color.

As answered in this question, even implementing screen and multiply is not trivial in OpenGL, so I doubt there's a way you can do them both at the same time.

How to handle alpha in a manual Overlay blend operation?

Just a guess, but I would try

resultA = 1 - (1-baseAlpha) * (1-blendAlpha)


Related Topics



Leave a reply



Submit