5

我正在玩一些手动(步行像素)图像处理,并且我正在重新创建标准的“叠加”混合。我在这里查看“Photoshop 数学”宏:

http://www.nathanm.com/photoshop-blending-math/ _ _ _

两个源图像都采用相当标准的 RGBA(每个 8 位)格式,目标图像也是如此。当两个图像完全不透明(alpha 为 1.0)时,结果将按预期正确混合:

但是,如果我的“混合”图层(顶部图像)具有透明度,那么对于如何将 alpha正确地考虑到混合方程中,我会感到有些困惑。我希望它能够工作,这样混合层中的透明像素对结果没有影响,混合层中的不透明像素正常进行覆盖混合,半透明混合层像素对结果有一些缩放效果。

有人可以向我解释混合方程或这样做背后的概念吗?

如果你能帮我做到这一点,那么得到的图像具有正确的预乘 alpha 值(我认为,这只对两层中不透明的像素起作用。)

谢谢!

// factor in blendLayerA, (1-blendLayerA) somehow?
resultR = ChannelBlend_Overlay(baseLayerR, blendLayerR); 
resultG = ChannelBlend_Overlay(baseLayerG, blendLayerG);
resultB = ChannelBlend_Overlay(baseLayerB, blendLayerB);
resultA = 1.0; // also, what should this be??
4

4 回答 4

5

混合基色和混合色后,使用混合色的 alpha 混合原始基色和混合产生的颜色:

vec4 baseColor = ...;
vec4 blendColor = ...;
vec4 blendedColor = blend(baseColor, blendColor);
vec4 fragmentColor = (1.0 - blendColor.a) * baseColor + blendColor.a * blendedColor;

我将其用于“叠加”混合不透明的基色和具有大量(半)透明像素的混合纹理。

于 2013-09-23T10:09:47.203 回答
1

只是一个猜测,但我会尝试

resultA = 1 - (1-baseAlpha) * (1-blendAlpha)
于 2011-01-14T08:37:04.673 回答
0

我一直在试验这个问题,直到我发现最好的办法是让基础层和混合层都使用直接 alpha,然后只用基础 alpha 预乘结果。

于 2012-05-13T22:37:05.973 回答
0

这很好用,使用这里的公式:https ://dev.w3.org/SVG/modules/compositing/master/ 。我的函数有点古怪,因为它接受一个 0-1 的 DoubleColor 和一个 0-maxValDouble() 的 T* 像素颜色(这是使用的整数类型的最大值,作为双精度)。

template<typename T> static inline void blendColorOverlay(T* rgba, DoubleColor overColor) {
    if (overColor.a == 0)
        return;
    
    double Da = rgba[3]/maxValDouble<T>();
    double Sa = overColor[3];
    double Dca, Sca;
    
    double outAlpha = (Sa + Da - Sa*Da);
    
    for (int k = 0; k < 3; k++) {
        Dca = (rgba[k]/maxValDouble<T>())*Da;
        Sca = overColor[k]*Sa;
        if (2*Dca <= Da)
            rgba[k] = (2*Sca*Dca + Sca*(1.0 - Da) + Dca*(1.0 - Sa))*maxValDouble<T>()/outAlpha;
        else
            rgba[k] = (Sca*(1.0 + Da) + Dca*(1.0 + Sa) - 2.0*Dca*Sca - Da*Sa)*maxValDouble<T>()/outAlpha;
        }
        
    rgba[3] = outAlpha*maxValDouble<T>();
    }
于 2021-10-21T21:09:15.860 回答