手动混合一个RGBA像素和一个RGB像素

27

我正在尝试对一张RGBA图像(前景图像)进行Alpha混合操作,将其覆盖在一张RGB图像(背景图像)上。然而,在这样做时,我认为我可能正在执行错误的Alpha混合操作或者操作不正确。例如,我的RGB图像像素是灰色的(127, 127, 127),而相应的RGBA图像像素是(0, 0, 255)。在进行混合操作后,最终颜色将会是(127, 0, 255)。但是,我认为这更像是加法混合,与我所做的混合操作不同。

要查看我的值是如何设置的,请看这里

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)

要了解我的计算方式,请看这个

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);

对于没有 alpha 通道的像素,我希望值为 (0, 0, 255),对于有 alpha 的图像,我希望它能混合。在上述操作结束时,它将为 (127, 127, 255)。我应该检查每个像素是否有 alpha 通道,并且如果有,那么进行混合,还是有其他方法可以做到这一点?


你正在进行加法混合。考虑使用线性混合,如下所示:y = (x0 * w) + (x1 * (1-w)) - Osman Turan
1
这是很多的255缩放来回。如果您的操作保持归一化,那么这是不必要的。 - fche
请在此处查看我的解释:https://dev59.com/p1zUa4cB1Zd3GeqP4I3c#73498765 - Slyv
2个回答

32

通常,“Over”混合是按以下方式完成的:

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

然后重复上述步骤,分别对蓝色和绿色通道进行操作。对于每个像素都执行此操作。


也许我错了,但这不是我已经在做的吗? - mmurphy
不,你现在做的是outputRed = (foreRed * foreAlpha) + backgroundRed。你需要将backgroundRed乘以(1.0 - foreAlpha)。 - user1118321
最终结果也是透明的。因此,如果您有一个覆盖率为0%(alpha)的源像素,它不应该对输出产生影响。如果您将其叠加在覆盖率为0%的像素上,则背景也不应对输出产生影响。因此,结果将是RGBA =(0,0,0,0)。可以说是“透明黑色”。如果您将结果叠加在非透明物体上,则会看到您叠加的内容。 - user1118321
这是否假定foregroundAlpha在0-255范围内或0-1范围内? - Julian
它假设alpha在0-1范围内。 - user1118321
显示剩余2条评论

2

看起来您在背景(currentPixelColor)的(1-Alpha)倍数上遗漏了一部分。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接