假设我有两种颜色,一种是 src ,另一种是 dst 。它们都有4个通道(RGBA)。每个通道的大小为8位(0x00 - 0xFF)。
如果 src 位于 dst 之上,根据Alpha compositing,我会得到 out 颜色:
所以,如果我有合成的颜色 out 和 src ,我可以得到 dst 颜色:
在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颜色?
答案 0 :(得分:1)
我担心一般来说你想要的东西根本不可能,因为精确度会下降。
想象一下你的dstAlpha是例如0x0F,那么任何目标颜色值(从0x00到0xFF)的输出范围都会被压缩到0x00到0x0F,最多。然后根本没有足够的信息来恢复原始值。
如果从8位只保留4位,那么你将无法从空中恢复其他4位。 α越低,精度损失越大。