PNG位扩展

时间:2015-08-19 09:27:38

标签: bitmap bit-manipulation png pixel

我正在编写PNG解码器并且我遇到了具有位深度<的灰度图像的问题。 8。

我不知道如何才能获得全彩色范围。

例如,假设图像使用4位深度,而数据字节为:10110010 我有2个像素,10110010。现在,我将第二个像素移位4位以占据高位。这就是问题所在。我应该复制位,以便2个像素为1011101100100010,或者我应该只扩展最后一位,以便像素为1011111100100000。我在PNG规范中找不到相关信息。

1 个答案:

答案 0 :(得分:1)

为什么这会符合规格?您正在转换输出值,并且规范不应该关心您对输出数据的处理方式。尽管如此,正如Glenn Randers-Pehrson所说,official specification包含了相关的建议。 Concepts: 4.3.6 Sample depth scaling介绍了基础知识。编码器和解码器的建议在12.5 Sample depth scaling中用于编码器(将外部数据扩展到支持的PNG格式)和13.12 Sample depth rescaling用于解码器(将PNG格式扩展为所需的输出格式)。

那就是说,假设你想要一个4位值1111线性转换为8位值1111.1111,那么公式为

output = 255 * input / 15

将公式应用于0..15范围,即可获得

 0: 0000 -> 00000000
 1: 0001 -> 00010001
 2: 0010 -> 00100010
 3: 0011 -> 00110011
 4: 0100 -> 01000100
 5: 0101 -> 01010101
 6: 0110 -> 01100110
 7: 0111 -> 01110111
 8: 1000 -> 10001000
 9: 1001 -> 10011001
10: 1010 -> 10101010
11: 1011 -> 10111011
12: 1100 -> 11001100
13: 1101 -> 11011101
14: 1110 -> 11101110
15: 1111 -> 11111111

如您所见,前四位始终在低位重复。那是完全上面的公式!

  255 * input / 15
= input * 255 / 15
= input * 17
= input + input * 16

我们最终以

结束
output = (input<<4) + input

这可以扩展到上采样(和下采样)任何值到另一个基数:

newvalue = (oldvalue * max_new) / max_old

由于max_new通常对于位值是奇数,为了获得适当的舍入,您可以使用

newvalue = (2 * oldvalue * max_new + max_old) / (2*max_old)