8

一般来说,“正常”混合模式方程如下所示:

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

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

现在,这适用于完全不透明的目的地,但我想知道你将如何处理半透明和完全透明的目的地。

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

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

4

3 回答 3

10

这个方程是一般混合方程的简化。它假定目标颜色是不透明的,因此会删除目标颜色的 alpha 项。

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

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

Da = C1a + C2a * (1 - C1a)

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

于 2009-11-12T20:28:07.940 回答
1

我发现这个答案很有帮助,并且在将相同的公式应用于 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;
}

This works well for quick and dirty code, but there are faster approaches as well, as commented in the above answer, but also addressed here and here.

于 2016-12-10T11:32:34.677 回答
0

大多数混合公式用于未存储目标颜色 alpha 的静态图像。如果 alpha 可用,那么最终的 alpha 将只是源 alpha 和目标 alpha 的算术平均值

您可以计算平均 alpha,然后在公式中简单地使用它来代替“Sa”。

介意告诉我们这是干什么用的?

于 2009-11-12T20:38:08.483 回答