透明和半透明背景上的混合模式

时间:2009-11-12 19:57:25

标签: algorithm graphics blend

通常,“正常”混合模式等式如下所示:

D = Sa * S + D * (1.0 - Sa)

其中D是目标颜色,Sa是源alpha,S是源颜色。

现在,这适用于完全不透明的目标,但我想知道如何使用半透明目标和完全透明目标来处理它。

当在完全透明的目的地上混合源时,源像素(像素为颜色和alpha)将保持不变,并且不像以前的等式那样混合,如果目标背景完全不透明,则上面的等式应该是应用,但我找不到一个很好的方法来处理目标alpha在0和1之间的情况。

例如,如果在透明背景上混合白色像素和50%alpha,则颜色不应该倾向于透明颜色值(或多或少处于未定义状态),目标颜色应为全白,而不是50%(在alpha乘法之后),这是你在应用上面的等式后得到的(如果D与S的颜色相同,这是我想到的)。

3 个答案:

答案 0 :(得分:7)

该等式是一般混合方程的简化。它假定目标颜色是不透明的,因此会删除目标颜色的alpha术语。

D = C1 * C1a + C2 * C2a * (1 - C1a)

其中D是结果颜色,C1是第一个元素的颜色,C1a是第一个元素的alpha,C2是第二个元素颜色,C2a是第二个元素的alpha。目标alpha使用以下公式计算:

Da = C1a + C2a * (1 - C1a)

将得到的颜色与alpha预乘。要将颜色恢复为未经过相乘的值,只需除以Da即得到的alpha值。

答案 1 :(得分:1)

我发现此answer有用,并且在将相同的公式应用于Alpha通道时似乎可以正常工作。

此处更改以显示扩展版本:

int blend(unsigned char result[4], unsigned char fg[4], unsigned char bg[4] {
    unsigned int alpha = fg[3] + 1;
    unsigned int inv_alpha = 256 - fg[3];
    result[0] = (unsigned char)((alpha * fg[0] + inv_alpha * bg[0]) >> 8);
    result[1] = (unsigned char)((alpha * fg[1] + inv_alpha * bg[1]) >> 8);
    result[2] = (unsigned char)((alpha * fg[2] + inv_alpha * bg[2]) >> 8);
    result[3] = (unsigned char)((alpha * fg[3] + inv_alpha * bg[3]) >> 8);
    // result[3] = 0xff;
}

这适用于快速而肮脏的代码,但也有更快的方法,如上面的答案所述,但也解决了herehere

答案 2 :(得分:0)

大多数混合公式用于未存储目标颜色alpha的静态图像。如果alpha可用,那么最终的alpha就是源alpha和目标alpha的arithmetic mean

您可以计算平均值,然后在公式中的“Sa”位置使用它。

介意告诉我们这是为了什么?