0

作为我家庭作业的一部分,我应该用 Python 编写一个简单的 PNG 阅读器。我被禁止使用任何处理图像的 Python 库,因此我应该有一个单像素 RGB 元组的列表列表(图像行)。

解码器应该只读取最基本的 PNG 图像,这些图像仅包含 IHDR、IDAT 和 IEND 块,IDAT 仅包含基本的 RGB 数据。到目前为止,我的程序检查正确的 PNG 标头并使用zlib.decompress()解压缩 IDAT 块。

在这个阶段,我被困了好几天。zlib decopress 将图像数据保留在状态中,其中我有图像行的字节表示,如下所示:

每行以 1 个字节开始,0x00、0x04、0x02 或 0x01。我发现 0x00 表示该行在“原始数据”中,这意味着下一个字节代表像素的 R、G 或 B 等等,直到行尾(没有实际的换行符,而是另一个“标题”字节”)。0x04 或 0x02 然而,正如我所读的那样,它是用霍夫曼编码编码的,这就是我的问题:

如何解码这些行? 是否有用于此的 python 函数(就像有用于 inflate 步骤的 zlib 解压缩一样)另外,最后 2 行以 0x01 开头,正如我所读到的 Deflate 应该意味着“这是流中的最后一个块”。为什么我在图像的最后两行有它,而不仅仅是最后一行?最后两行的数据也很混乱,因为有些像素显然是“原始”表示,但有些不是。

非常感谢,我已经尝试在任何地方找到我的答案......

沃伊塔

4

2 回答 2

2

霍夫曼编码是zlib.decompress已经为您撤消的放气压缩的一部分。根据PNG 规范的第 4.5.4 节,每个扫描线的第一个字节是过滤器类型,过滤器在第 9 节中描述。

于 2013-06-13T11:47:03.333 回答
1

每行的第一个数据字节不影响压缩:它告诉在压缩之前对数据运行了哪个预过滤器,它可以是 0 到 4。这在http://www.w3.org/中有描述TR/PNG-Filters.html。顺便说一句,你可以责怪我——为每条扫描线使用不同的过滤器的想法是我的。:-)

于 2013-06-14T00:37:02.227 回答