PNG文件解读(3):图像数据块IDAT细节—PNG压缩与解码编码详解
Author:zhoulujun Date:
PNG IDAT 压缩数据细节
在 PNG Spec 压缩算法部分:
PNG compression method 0 is deflate/inflate compression with a sliding window (which is an upper bound on the distances appearing in the deflate stream) of at most 32768 bytes. Deflate compression is an LZ77 derivative [ZL].
Deflate-compressed datastreams within PNG are stored in the "zlib" format, which has the structure:
- zlib compression method/flags code 1 byte
- Additional flags/check bits 1 byte
- Compressed data blocks n bytes
- Check value 4 bytes
Further details on this format are given in the zlib specification [RFC-1950].
总结如下:
PNG 使用 DEFLATE 压缩算法。
DEFLATE 是同时使用了 LZ77 算法与哈夫曼编码(Huffman Coding)的一个无损数据压缩算法。
DEFLATE 压缩的数据以 zlib 格式存储。
关于zlib与gzip
zlib(RFC1950):一种格式,是对 deflate 进行了简单的封装,他也是一个实现库(delphi中有zlib,zlibex)
zlib = zlib 头 + deflate 编码的实际内容 + zlib 尾
gzip(RFC1952):一种格式,也是对 deflate 进行的封装。
gzip = gzip 头 + deflate 编码的实际内容 + gzip 尾
gzip,zip压缩格式和png图像格式的本质压缩算法都是基于DEFLATE及其实现。
zib官网:http://www.zlib.net/
DEFLATE:https://en.wikipedia.org/wiki/DEFLATE
关于png具体算法,这里避过了。
提取&解压 IDAT 中压缩数据
Windows 上可以用 [hexeditor](https://www.hhdsoftware.com/free-hex-editor)
Mac 上可以用 [hexfiend](http://ridiculousfish.com/hexfiend/)、[Hopper Disassembler](https://www.hopperapp.com/)
PNG压缩过程
PNG压缩过程分为两个阶段:Prediction 和 Compression。
Prediction
在这一阶段,我们每次会处理图片中一行的数据,首先通过Filter阶段处理这一行当中每一个的像素点中每条通道的值,也就是我们常说的ARBG。它交由差分处理器来重新计算该通道的值。差分处理会根据这个像素点上通道和之前或者之上像素点对应通道值之间的差异,进行差分编码,也就是说,如果原本相邻像素点之间通道的值之间很接近,那么我们就会获得很多的1,0,-1这种很小的值。这里有两点需要注意:
整个Prediction阶段的目的,也就是选择合适的差分处理器,让最终的编码结果出现尽可能多的零值和重复值,这一结果将会影响到Compression阶段的压缩率。
差分编码器比较的是像素点之间对应通道的值,而并不是整个像素点。
Compression
在Prediction处理完毕之后,再将这一转换的结果输出给Deflate,Deflate执行真正的压缩操作,它会通过LZ77和Huffman对图像进行编码,最后将处理之后的结果保存。在Compression阶段,它最终的压缩率会受到两方面的影响:
Prediction 的处理结果:对于颜色相近的区域,也就是有很多零值的区域,那么压缩率将会更高,而如果颜色之间差异很大,那么压缩效果将不尽人意。所以:
如果原始的图片为高清的,但是不要求进行无损的压缩,那么可以选择类似于JPG这样的有损压缩
但是从反方面来说,如果原始图片较为简单,并且需要支持透明形式,那么PNG要由于JPG。
Deflate 每一行的匹配情况:前面我们分析过,整个处理过程是按行来处理的。而在处理每一行的数据时,Deflate把处理的符号数限制为3 ~ 258,也就是说,最大的压缩率为1032:1,当出现符号数小于3个时,那么就有可能出现无法匹配的情况,因此,对于图片宽度的改变将有可能影响最终压缩的效果。
代码表示
对于 Prediction 和 Compression 这两个过程,可以通过下面这个代码来理解:
https://gist.github.com/anonymous/906740
PNG图片压缩工具
网上流行的PNG压缩工具主要有ImageAlpha、ImageOptim、pngcrush、optipng、pngout、pngnq、advpng等。
tinypng、pngquant、ImageAlpha、pngnq都是有损压缩,基本采用的都是quantization算法,将24位的PNG图片转换为8位的PNG图片,减少图片的颜色数;
pngcrush、optipng、pngout、advpng都是无损压缩,采用的都是基于LZ/Huffman的DEFLATE算法,减少图片IDAT chunk区域的数据。一般有损压缩的压缩率会大大高于无损压缩。
pngquant
根据官网 https://pngquant.org/介绍,pngquant是国外的一个有损的PNG压缩开源库,提供了命令行形式和源码库形式。将24位或32位的RGBA PNG图转换成8位PNG图并保留透明度通道。通过这个库的转化可以显著减少png文件大小(通常减少70%)。生成的图片文件可以兼容所有现代web浏览器,在IE6下比24-bit PNGs也有更好的表现。它的特性有:
结合Vector_quantization算法生成高质量的色彩范围;
独特的自适应抖动算法,比标准的FloydSteinberg算法具有更强的抗噪性;
易与集成,提供了shell脚本,图形化界面,服务端库,PS插件;
具有快速模式,用于处理大批图片。源码库地址为pngquant。
参考文章:
音视频入门-11-PNG文件格式详解 https://www.cnblogs.com/binglingziyu/p/audio-video-basic-11-png-file-format-detail.html
图片压缩知识梳理(1) - PNG 原理 https://www.jianshu.com/p/5ad19825a3d0
图片压缩知识梳理(2) - 减小 PNG 大小 https://www.jianshu.com/p/324744087e24
转载本站文章《PNG文件解读(3):图像数据块IDAT细节—PNG压缩与解码编码详解》,
请注明出处:https://www.zhoulujun.cn/html/theory/multimedia/CG-CV-IP/8411.html