RGBA,与每个通道8位大小的alpha合成的反向,以C为单位

时间:2013-11-18 09:02:26

标签: c colors int precision alphablending

假设我有两种颜色,一种是 src ,另一种是 dst 。它们都有4个通道(RGBA)。每个通道的大小为8位(0x00 - 0xFF)。

如果 src 位于 dst 之上,根据Alpha compositing,我会得到 out 颜色:

  • out_ A = src_ A + dst_ A *(1 - src_ A
  • OUT_ RGB =(src_ RGB * src_ A + dst_ RGB * dst_ A < / em> *(1 - src_ A ))/ out_ A

所以,如果我有合成的颜色 out src ,我可以得到 dst 颜色:

  • dst_ A =(out_ A - src_ A )/(1 - src_ A
  • dst_ RGB =(out_ RGB * out_ A - src_ RGB * src_ A < / em>)/((1 - src_ A )* dst_ A

在C中,如果每个通道必须使用8位。我得到了alpha合成代码:

/*
 * [0] - R
 * [1] - G
 * [2] - B
 * [3] - A
 */
uint8_t src_raw[4], dst_raw[4], composed[4];
float src[4], dst[4], out[4];

/*
 * We get the src_raw and dst_raw color,
 * now calculate the composed color.
 */

for (int i = 0; i < 4; ++i) {
    src[i] = src_raw[i] / 255.0f;
    dst[i] = dst_raw[i] / 255.0f;
}

out[3] = src[3] + dst[3] * (1 - src[3]);
for (int i = 0; i < 3; ++i) {
    out[i] = (src[i] * src[3] + dst[i] * dst[3] * (1 - src[3])) / out[3];
}

for (int i = 0; i < 4; ++i) {
    composed[i] = out[i] * 0xFF;
}

合成的反转是smae,但是编组 src 来计算 dst

问题是从uint8_t投射到float,从float计算并投射到uint8_t时,我失去了精确度。

例如,如果dst_raw = {0, 0, 255, 128}src_raw = {128, 0, 0, 64},我会获得撰写的颜色{51, 0, 152, 159}。但是当composed = {51, 0, 152, 159}src_raw = {128, 0, 0, 64}时,我会得到dst_raw颜色{0, 0, 254, 126}

我的问题是:当使用8位大小反转alpha合成来表示一个频道时,如何获得正确的dst_raw颜色?

1 个答案:

答案 0 :(得分:1)

我担心一般来说你想要的东西根本不可能,因为精确度会下降。

想象一下你的dstAlpha是例如0x0F,那么任何目标颜色值(从0x00到0xFF)的输出范围都会被压缩到0x00到0x0F,最多。然后根本没有足够的信息来恢复原始值。

如果从8位只保留4位,那么你将无法从空中恢复其他4位。 α越低,精度损失越大。