了解PNG文件格式IDAT段

时间:2013-11-10 13:58:11

标签: c++ parsing graphics png

从下面的示例图片中,我有一个黄色边框仅用于显示目的。

实际的.png文件是3像素乘3像素的简单黑白图像。我原本打算尝试2x2,但这无助于尝试解释低/高与高/低绘图流。至少这样,我会有两个黑色,一个白色从顶部,或一个白色,两个黑色从底部..

所以我读了数据块,得到了IDAT块,解码了(zlib)并得到了12个字节,如下所示

00 20 00 40 00 80

所以,我的问题是,如何将上述内容分解为3x3黑白样本...此外,它以调色板格式保存并正确识别1的位深度和2 ...颜色的调色板托盘[0]是RGBA全零。调色板1的RGBA为255,255,255,0

我最终会进入其他多种深度格式,只是想从最简单的方式开始。

第二部分。任何关于处理其他深度格式的指导都会有所帮助,如果有什么特别的东西可以考虑,特别是关于alpha通道(我已经在调色板中寻找)可能会让我失望。

enter image description here

1 个答案:

答案 0 :(得分:5)

如果您使用libpng,它会更容易,所以我想这是出于学习目的。

问题是,如果您直接解压缩IDAT块,您会得到一些不应该显示的数据和/或可能需要转换(因为应用了过滤器)才能获得实际字节数。在PNG格式中,每一行都以一个额外字节开头,该字节告诉您哪个过滤器应用于该行,其余字节包含行像素。

BTW,00 20 00 40 00 80仅为6个字节(不是12,如您所想)。现在,如果您将此数据视为二进制,则您的3行将如下所示:

  <00> 00000000 00100000
  00000000 01000000
  00000000 10000000

现在,您的图像是每像素1位,因此需要1个字节来保存3个像素的行。实际使用了3个最高位(忽略了5个低位)。我用x替换了忽略的位,所以我认为更容易看到实际的像素0是黑色的,1是白色的):

  

00000000 001xxxxx
  00000000 010xxxxx
  00000000 100xxxxx

在这种情况下,没有过滤器应用于任何行,因为每行的第一个字节为零(0表示未应用过滤器,从14的值表示过滤器被应用)。