Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

小蝌蚪传记:PNG图片压缩原理--屌丝的眼泪 #1

Open
airuikun opened this issue Mar 21, 2019 · 29 comments
Open

小蝌蚪传记:PNG图片压缩原理--屌丝的眼泪 #1

airuikun opened this issue Mar 21, 2019 · 29 comments

Comments

@airuikun
Copy link
Owner

airuikun commented Mar 21, 2019

背景

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

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

同意好友申请以后,仔细看了她这十年间所有的qq动态和照片。
她变美了,会打扮了,以前瘦瘦的身材配上现在的装扮和妆容,已经是超越我认知的女神了。

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

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

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

什么是PNG

PNG的全称叫便携式网络图型(Portable Network Graphics)是目前最流行的网络传输和展示的图片格式,原因有如下几点:

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

  • 体积小:它利用特殊的编码方法标记重复出现的数据,使得同样格式的图片,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(0255),G(0255),B(0~255),可以表达256乘以256乘以256=16777216种颜色的图片,这样PNG 24就能比PNG 8表示色彩更丰富的图片。但是所占用的空间相对就更大了。

  • PNG 32:PNG 32中的32,相当于PNG 24 加上 8bits的透明颜色通道,就相当于R(红)、G(绿)、B(蓝)、A(透明)。R(0255),G(0255),B(0255),A(0255)。比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请求的结构很像,都是一个数据头,后面跟着很多的数据块,如下图所示:

image

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

image

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

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

8950 4e47 0d0a 1a0a:这个是PNG图片的头,所有的PNG图片的头都是这一串编码,图片软件通过这串编码判定这个文件是不是PNG格式的图片。

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

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

0000 02bc:是图片的宽度。

0000 03a5:是高度。

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

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

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

image

它仅仅由红色和绿色构成,如果用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图片如下:

image

这张图片是一个红色逐渐增强的渐变色图,它的红色从左到右逐渐加强,映射成数组的值为[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格式前后对比效果如下图所示:

image

可以看到,导出web格式,去除了很多无用信息后,图片明显小了很多。

结语

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

想起那年跟初恋分手的原因 是因为怕影响到学习。。。可是分开后成绩也还是很烂,不仅错过了女神,而且到现在也依然一事无成。

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

就像鲁迅说的:

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

。。。。。。

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

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

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

再见

作者:第一名的小蝌蚪

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

交流

欢迎关注我的微信公众号,微信扫下面二维码或搜索“前端屌丝”,讲述了一个前端屌丝逆袭的心路历程,共勉。

image

@idseventeen
Copy link

如此幽默的一篇文章,有趣~😄

@liyxPro
Copy link

liyxPro commented Apr 2, 2019

对化妆的过程如此熟悉👏

@Jveen-D
Copy link

Jveen-D commented Apr 8, 2019

鲁迅说:“张爱玲说过,爱情就像在沙滩上捡贝壳......”

@medsciJs
Copy link

medsciJs commented Apr 9, 2019

还是你够秀

@ChenXi996
Copy link

大哥乃地瓜之秀!

@mackxu
Copy link

mackxu commented Apr 15, 2019

喜欢最漂亮的

@EEETA
Copy link

EEETA commented Apr 18, 2019

模糊图片变清晰也可以讲一下

@xiaomao996688
Copy link

鲁迅说:“张爱玲说过,爱情就像在沙滩上捡贝壳......”

啥含义

@Assan233
Copy link

就不怕老婆看到嘛....233333333

@maixiaojie
Copy link

秀儿

@lovelydong
Copy link

###怎么感觉学着学着被强塞了一口狗粮

@ligq4
Copy link

ligq4 commented May 13, 2019

这骚气的文笔比技术更胜一筹

@Chen4u
Copy link

Chen4u commented May 13, 2019

666

@modupantu
Copy link

哈哈

@hunterlord
Copy link

编程什么的放弃吧,出去站街才是你的出路

@Flushd
Copy link

Flushd commented May 16, 2019

编程什么的放弃吧,出去站街才是你的出路

跟你🐴一样有出路? @hunterlord

@maskonface
Copy link

should use the first line as the title

@PLQin
Copy link

PLQin commented May 16, 2019

should use the first line as the title

hhh, 精辟

@icysonyk
Copy link

一开始被楼主的故事吸引,结果看到讲解png的时候居然认认真真的看完了

@qiutian00
Copy link

有趣,感觉是楼主自己的故事😂😂

@Achilles822
Copy link

有这样的文笔还写什么代码呢?

@stupidehorizon
Copy link

不怕老婆看见这篇文章吗?

@worldofpeople
Copy link

@airuikun airuikun changed the title PNG图片压缩原理--屌丝的眼泪 小蝌蚪传记:PNG图片压缩原理--屌丝的眼泪 Jun 23, 2019
@EdwinRoyXie
Copy link

抄袭我伦的歌词

@llorz-o
Copy link

llorz-o commented Aug 22, 2019

鲁迅:"别tm瞎说,我可没说过"

@baohangxing
Copy link

你太秀了

@ZhangNinth
Copy link

模糊图片变清晰也可以讲一下

你说的是渐进式图片吧

@zhoulujun
Copy link

zhoulujun.cn,个人博客里面相关的,暂时先整理这些吧,算不算广告?

色彩基础理论

解读png的

解读jpg的

视频的

拓展的

目前图形可是化,菜鸟

@myongong
Copy link

女神分类让我想起了西游记土地神介绍蟠桃园,三千年一开花三千年一结果,吃上一口延年益寿

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests