Manually alpha blending an RGBA pixel with an RGB pixel
Asked Answered
Q

2

27

I am trying to do an alpha blend operation of an RGBA image (foreground image), on to a RGB image (background image). However, while doing so I think I may be doing the wrong alpha blending operation or doing it wrong. For example, the pixel of my RGB image is a grayish color of (127, 127, 127). The pixel of my RGBA image for the pixel will be (0, 0, 255). After I do my blending operation, the final color will be (127, 0, 255). However, I thought that was more of an additive blend and different than the operation I am doing.

For how my values are set, take a look at this

incPixelColor[0] = 0; (red)
incPixelColor[1] = 0; (green)
incPixelColor[2] = 255; (blue)
incPixelColor[3] = 255; (alpha)

currentPixelColor[0] = 127; (red)
currentPixelColor[1] = 127; (green)
currentPixelColor[2] = 127; (blue)

For how my calculation is set, take a look at this

float incAlpha = (currentPixelColor[3]/255.0f);

float red = ((float)incPixelColor[0]/255.0f * incAlpha) + ((float)currentPixelColor[0]/255.0f);
float green = ((float)incPixelColor[1]/255.0f * incAlpha) + ((float)currentPixelColor[1]/255.0f);
float blue = ((float)incPixelColor[2]/255.0f * incAlpha) + ((float)currentPixelColor[2]/255.0f);


currentPixelColor[0] = min(red * 255, 255.0f);
currentPixelColor[1] = min(green * 255, 255.0f);
currentPixelColor[2] = min(blue * 255, 255.0f);

For pixels with no alpha, I would like for the value to be (0, 0, 255) then for images with alpha I would like for it to blend in. At the end of the operation above, it will be (127, 127, 255). Should I check to see if there is alpha for every pixel, and if so, then do the blend or is there another way to do this?

Quicklime answered 26/1, 2012 at 6:43 Comment(3)
You're doing additive blending. Consider linear mixing like this: y = (x0 * w) + (x1 * (1-w))Purple
That's a lot of 255 scaling back and forth. It should not be necessary if your operations maintain normalization.Scoreboard
Please check my explanation here: https://mcmap.net/q/534784/-opengl-alpha-blendingYvette
A
32

A typical "Over" blend is done in the following way:

outputRed = (foregroundRed * foregroundAlpha) + (backgroundRed * (1.0 - foregroundAlpha));

And then repeating for the blue and green channels. Do this for every pixel.

Ain answered 26/1, 2012 at 6:48 Comment(7)
Perhaps I am mistaken, but isn't that what I am already doing?Quicklime
No, what you're doing is outputRed = (foreRed * foreAlpha) + backgroundRed. You need to multiply the backgroundRed by the (1.0 - foreAlpha).Ain
Sorry that so late, but what happens to the alpha output alpha channel if both destination and source pixels are transparent?Effendi
It ends up transparent, too. So if you have a source pixel with 0% coverage (alpha), it shouldn't contribute to the output. If you overlay that on a pixel with 0% coverage, the background also shouldn't contribute to the output. So the result will be RGBA = (0,0,0,0). It will be "transparent black" so to speak. If you overlay the result on something that's not transparent, you'll see whatever you overlaid it on.Ain
Does this assume that foregroundAlpha is in the 0-255 range or 0-1 range?Whitnell
It assume alpha is in the 0-1 range.Ain
This formular makes a 50% red on white background into a rgb(255, 128, 128) which is mathematically correct. Under macOS I notice Chrome, Safari and even Sketch App blend that setup into rgb(255, 138, 138). Firefox rgb(255, 126, 124). Photoshop sticks to the 128 though. So interestingly some software takes extra steps for whatever reasons and 50% red is not universally 50% red Pen: codepen.io/timohausmann/pen/rNLdpwJ?editors=0100 macOS Screenshot: imgur.com/a/2ioPPiyMackenie
F
2

It seems that you have missed out (1-Alpha) multiplier for background (currentPixelColor)

Few answered 26/1, 2012 at 12:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.