PNG按以下顺序是Filters + LZ77 + Huffman的组合(LZ77 + Huffman的组合称为Deflate):
第1步),如果滤镜不同于“无”,则将像素值替换为与相邻像素的差值(有关更多详细信息,请参见http://www.libpng.org/pub/png/book/chapter09.html) 。这会增加具有梯度的图像的压缩率(因此... 4 5 6 7变为... 1 1 1 1),并且可能在相同颜色的区域中有所帮助(... 3 3 3 5 5 5 5 5变为0 0 0 2 0 0 0 0 0)。默认情况下,使用调色板在24位图像中启用过滤器,并在8位图像中禁用过滤器。
步骤2)使用LZ77压缩数据,该LZ77用包含到匹配距离和匹配长度的元组替换重复的(匹配)字节字符串。
步骤3)使用霍夫曼码对步骤2的结果进行编码,该霍夫曼码将可变长码替换为固定长度符号,符号越频繁,代码越短。
存在多个问题:
一个影响很少像素的小变化将导致png压缩的3个步骤的结果发生变化:
1)相邻像素的滤波值将改变(取决于所使用的滤波器)。这将放大小的变化的影响。
2)更改将意味着与该区域的匹配将有所不同。例如,将333333更改为333533会导致333333的另一个匹配项不再匹配,因此它将选择另一个与333333匹配的对象,且匹配距离不同,或者将选择相同的匹配对象,但长度较短,然后再匹配最后3个字节。本身将极大地改变结果。
3)最大的问题是在第3步中。霍夫曼代码使用可变数量的位,因此即使很小的变化也将导致后面的所有内容不再对齐。AFAIK大多数压缩算法无法检测到未按字节对齐的匹配项,因此除非压缩程序可以检测到未按字节对齐的匹配项,否则将防止(或至少减少很多)对更改后已压缩的数据的压缩。
其他答复已涵盖其他问题:
4)Gzip使用具有32KB字典的相同Deflate算法,因此,如果png文件大于32KB,则即使它们相同也不会检测到匹配项。Bzip2在这方面更好,因为它使用900 KB的块。XZ使用LZMA,IIRC在默认压缩级别具有4 MB的字典。5)Zip格式不使用实体压缩,因此不会更好地压缩相似或相同的文件。
也许来自PAQ或PPMD系列的压缩器可以更好地压缩,但是如果您需要压缩大量相似的图像文件,则可以考虑以下三种方法:
1)存储未压缩的图像(使用PNG -0或未压缩的格式),并使用具有较大字典或块大小的压缩器进行压缩。(LZMA会很好地工作)
2)另一个选择是保留过滤器,但从PNG中删除Deflate压缩。例如,可以使用(AdvDef)实用程序来完成。然后,压缩生成的未压缩PNG。解压缩后,您可以保留未压缩的PNG或使用AdvDef再次对其进行压缩(但这将需要一些时间)。
您需要测试两种方法,以查看压缩率最高的方法。
3)最后一种选择是将视频中的png图像转换,使用无损视频压缩器(例如x264 lossless)进行压缩(特别注意使用正确的颜色格式),然后在提取时将帧提取为单个png图像。可以使用ffmpeg完成。您还需要保留帧号和原始名称之间的映射。
那将是最复杂的方法,但是如果png都是动画的一部分,则可能是最有效的。但是,如果需要,您将需要一种支持透明性的视频格式。
编辑:还有MNG格式将不经常使用。