PNG图片压缩原理解析

背景

今天凌晨一点,忽然有我的加个人qq,一看居然是十年前被我删掉的初恋。。。。前端

由于以前在qq空间有太多的互动,因此qq推荐好友里面常常推荐我俩互相认识。。。。谜之尴尬git

赞成好友申请之后,仔细看了她这十年间全部的qq动态和照片。 她变美了,会打扮了,之前瘦瘦的身材配上如今的装扮和妆容,已是超越我认知的女神了。github

而我依然碌碌无为,逐渐臃肿的身体加上日益上扬的发际线,天天为生活操劳和奔波,还穷。web

用一句话形容如今的感觉就是: “妳已经登上更高的巅峰 而我只能望着妳远去的背影”。算法

默默点了根烟,把她长得好看的照片都保存了下来。 咦?发现每一张照片都是.png的图片格式。 png??png的图片咱们天天都在用,但是png究竟是什么,它的压缩原理是什么? 很好,接下来我将会给你们一一阐述。vim

什么是PNG

PNG的全称叫便携式网络图型(Portable Network Graphics)是目前最流行的网络传输和展现的图片格式,缘由有以下几点:数组

  • 无损压缩:PNG图片采起了基于LZ77派生算法对文件进行压缩,使得它压缩比率更高,生成的文件体积更小,而且不损失数据。markdown

  • 体积小:它利用特殊的编码方法标记重复出现的数据,使得一样格式的图片,PNG图片文件的体积更小。网络通信中因受带宽制约,在保证图片清晰、逼真的前提下,优先选择PNG格式的图片。网络

  • 支持透明效果:PNG支持对原图像定义256个透明层次,使得图像的边缘能与任何背景平滑融合,这种功能是GIF和JPEG没有的。数据结构

PNG类型

PNG图片主要有三个类型,分别为 PNG 8/ PNG 24 / PNG 32。

  • PNG 8:PNG 8中的8,其实指的是8bits,至关于用2^8(2的8次方)大小来存储一张图片的颜色种类,2^8等于256,也就是说PNG 8能存储256种颜色,一张图片若是颜色种类不多,将它设置成PNG 8得图片类型是很是适合的。

  • PNG 24:PNG 24中的24,至关于3乘以8 等于 24,就是用三个8bits分别去表示 R(红)、G(绿)、B(蓝)。R(0~255),G(0~255),B(0~255),能够表达256乘以256乘以256=16777216种颜色的图片,这样PNG 24就能比PNG 8表示色彩更丰富的图片。可是所占用的空间相对就更大了。

  • PNG 32:PNG 32中的32,至关于PNG 24 加上 8bits的透明颜色通道,就至关于R(红)、G(绿)、B(蓝)、A(透明)。R(0~255),G(0~255),B(0~255),A(0~255)。比PNG 24多了一个A(透明),也就是说PNG 32能表示跟PNG 24同样多的色彩,而且还支持256种透明的颜色,能表示更加丰富的图片颜色类型。

怎么说呢,总的来讲,PNG 8/ PNG 24 / PNG 32就至关于咱们屌丝心中,把女神分为三类:

  • 一类女神 = PNG 8:屌丝舔狗们见到第一类女神,顿时会以为心情愉悦、笑逐颜开,屌丝发黑的印堂逐渐舒展,确认过眼神,是心动的感受。

  • 二类女神 = PNG 24:第二类女神开始厉害了,会给屌丝们一种菊花一紧、振聋发聩的心弦震撼,接触多了第二类女神能让屌丝天天精神抖擞,延年益寿。

  • 三类女神 = PNG 32:在第三类女神面前,全部的语言都显得苍白无力。那是一种看了让屌丝上下通透、手眼通天的至尊级存在。超凡脱俗、天神下凡都不足以描摹她美色的二分之一。我曾经只有在梦里才见到过。

哎。。。个人初恋,看着她如今的照片,应该是触及PNG 24这一等级了。

PNG图片数据结构

PNG图片的数据结构其实跟http请求的结构很像,都是一个数据头,后面跟着不少的数据块,以下图所示:

若是你用vim的查看编码模式打开一张png图片,会是下面这个样子:

握草,第一眼看到这一坨坨十六进制编码是否是感受和女神的心思同样晦涩难懂?

老弟 莫慌,讲实话,若是撩妹纸有那一坨坨乱码那么简单,哥哥我早就妻妾成群啦。 接下来我就一一讲解这一堆十六进制编码的含义。

8950 4e47 0d0a 1a0a:这个是PNG图片的头,全部的PNG图片的头都是这一串编码,图片软件经过这串编码断定这个文件是否是PNG格式的图片。

0000 000d:是iHDR数据块的长度,为13。

4948 4452:是数据块的type,为IHDR,以后紧跟着是data。

0000 02bc:是图片的宽度。

0000 03a5:是高度。

以此类推,每一段十六进制编码就表明着一个特定的含义。下面其余的就不一一分析了,太多了,小伙伴们本身去查吧。

什么样的PNG图片更适合压缩

常规的png图片,颜色越单一,颜色值越少,压缩率就越大,好比下面这张图:

它仅仅由红色和绿色构成,若是用0表明红色,用1表明绿色,那用数字表示这张图就是下面这个样子:

00000000000000000

00000000000000000

00000000000000000

1111111111111111111111111

1111111111111111111111111

1111111111111111111111111

咱们能够看到,这张图片是用了大量重复的数字,咱们能够将重复的数字去掉,直接用数组形式的[0, 1]就能够直接表示出这张图片了,仅仅用两个数字,就能表示出一张很大的图片,这样就极大的压缩了一张png图片。

因此!颜色越单一,颜色值越少,颜色差别越小的png图片,压缩率就越大,体积就越小。

PNG的压缩

PNG图片的压缩,分两个阶段:

  • 预解析(Prediction):这个阶段就是对png图片进行一个预处理,处理后让它更方便后续的压缩。说白了,就是一个女神,在化妆前,会先打底,先涂乳液和精华,方便后续上妆、美白、眼影、打光等等。

  • 压缩(Compression):执行Deflate压缩,该算法结合了 LZ77 算法和 Huffman 算法对图片进行编码。

预解析(Prediction)

png图片用差分编码(Delta encoding)对图片进行预处理,处理每个的像素点中每条通道的值,差分编码主要有几种:

  • 不过滤
  • X-A
  • X-B
  • X-(A+B)/2(又称平均值)
  • Paeth推断(这种比较复杂)

假设,一张png图片以下:

这张图片是一个红色逐渐加强的渐变色图,它的红色从左到右逐渐增强,映射成数组的值为[1,2,3,4,5,6,7,8],使用X-A的差分编码的话,那就是:

[2-1=1, 3-2=1, 4-3=1, 5-4=1, 6-5=1, 7-6=1, 8-7=1]

获得的结果为

[1,1,1,1,1,1,1]

最后的[1,1,1,1,1,1,1]这个结果出现了大量的重复数字,这样就很是适合进行压缩。

这就是为何渐变色图片、颜色值变化不大而且颜色单一的图片更容易压缩的原理。

差分编码的目的,就是尽量的将png图片数据值转换成一组重复的、低的值,这样的值更容易被压缩。

最后还要注意的是,差分编码处理的是每个的像素点中每条颜色通道的值,R(红)、G(绿)、B(蓝)、A(透明)四个颜色通道的值分别进行处理。

压缩(Compression)

压缩阶段会将预处理阶段获得的结果进行Deflate压缩,它由 Huffman 编码 和 LZ77压缩构成。

如前面所说,Deflate压缩会标记图片全部的重复数据,并记录数据特征和结构,会获得一个压缩比最大的png图片 编码数据。

Deflate是一种压缩数据流的算法. 任何须要流式压缩的地方均可以用。

还有就是咱们前面说过,一个png图片,是由不少的数据块构成的,可是数据块里面的一些信息实际上是没有用的,好比用Photoshop保存了一张png图片,图片里就会有一个区块记录“这张图片是由photshop建立的”,不少相似这些信息都是无用的,若是用photoshop的“导出web格式”就能去掉这些无用信息。导出web格式先后对比效果以下图所示:

能够看到,导出web格式,去除了不少无用信息后,图片明显小了不少。

结语

以上就是我对png的理解了,写的很差,就像一个支离破碎的中老年,杂乱无章。

想起那年跟初恋分手的缘由 是由于怕影响到学习。。。但是分开后成绩也仍是很烂,不只错过了女神,并且到如今也依然一事无成。

现在中年已至,身上背负着巨大的房贷,家里还有嗷嗷待哺的孩子,看着身旁呼噜声轰天熟睡中的妻子,忽然也就想开了。

就像鲁迅说的:

“爱情就像在海滩上捡贝壳,不要捡最大的, 也不要捡最漂亮的,要捡就捡本身最喜欢的, 最重要的是捡到了本身喜欢的 就永远不要再去海边了。”

。。。。。。

凌晨四点写完文章 不知不觉睡着了

梦回到十年前的那个夏天 咱们都笑的很甜

看着你哭泣的脸 微笑着对我说再见

再见

做者:第一名的小蝌蚪

github: 文章会第一时间分享在前端屌丝心路历程,欢迎star或者watch,感恩