我用 Photoshop 制作了一些 4x4 像素、16 位灰度的图像,并将它们保存为无压缩、无隔行,PNG 文件。我正在尝试编写一个程序来从这些文件中提取图像数据,但我对 IDAT 块有些困惑。这是为了自我学习而做的,所以我不使用库。
下面是其中一张图像的 IDAT 块的十六进制代码,其中每个像素都是白色。
我已经用颜色标记了我目前理解的部分:
红色 = 忽略此部分,因为它属于 IEND 块,与 IDAT 无关。
黄色 = 块信息。前 4 个黄色字节是数据长度。接下来的 4 个黄色字节是块标识符。图像末尾的最后 4 个黄色字节是循环冗余校验码。
蓝色 = zlib 压缩格式信息。第一个蓝色字节是压缩方法和压缩信息。第二个蓝色字节是标志信息。图像底部附近的最后 4 个蓝色字节是 ADLER-32 校验和。我假设在这种情况下没有 DICTID。
灰色 = Deflate 压缩算法的信息。第一个灰色字节中,第一位表示最后一个块标记,第二和第三位表示编码方法。忽略掉第一个灰色字节的其余部分。由于这种方法是非压缩方法,第二个和第三个灰色字节是块中数据字节的长度,第四和第五个灰色字节是第二个和第三个灰色字节的取反值。
无框 = 使用 LZ77 算法压缩的图像数据(由于是非压缩方法,没有哈夫曼编码),算法使用 8 位来表示潜在重复长度,15 位用于搜索距离。
我可能对某些事情的理解有误,或者没有正确理解如何使用LZ77算法解码没有边框的图像中的字节。如果有人能够纠正我或者展示我不理解的内容,我将不胜感激。谢谢。
(大小+12字节)
,至少在我测试的png上是一样的。 - Spektre