讲故事时间到了。
1.背景
上上周发布了简易的图片分割npm, 传入一个图片URL即可得到图片切片File数组。
当时的应用场景是: 为了解决页面首屏性能问题。
简单的运营页需要传背景图,但是一般背景图都比较大,大概 1M 左右,这就导致首屏时间较长(一般1M的加载+渲染要1000ms多),为了提升性能,基础侧提供图片切片能力、业务侧使用懒加载技术。
晚上的时候一个大哥问我, 一张PNG原图CDN压缩后大小是1.5M,拿到的切片数组第一张图大小是800KB,问我为啥会这样,大哥又追问了一句:如果用JPG格式会不会更好啊。
我脑子第一反应是, 众所周知PNG 比JPG 压缩效率更高。但我突然不知道个所以然了。
群哥在旁边突然来了句:“你知道PNG和JPG的存储是怎样的么?”
我:“没深入了解过”
群哥:“简单来说,PNG存储本质是一个MAP,这个MAP的value包含了所有RGB色值,PNG使用MAP的key,所以很多重复的地方可以用key去代替就好了。”
这种存储模式是索引彩色模式。GIF也采用该模式。
群哥:“而JPG是色值存储,它的每一个像素点都是RGB存储的。”
群哥:“就像我们写代码一样,对于重复率高的代码抽离成组件,可以减少整个项目的体积”
我:膜拜膜拜!!!
然后我就自己去搜索了下相关PNG 资料,简单如下。
后续的压缩都是指从原始图像压缩为 PNG/JPG 的过程。
2.定义
PNG, 便携式网络图型(Portable Network Graphics), 是一种采用无损压缩算法的位图格式。特点如下:
无损压缩, 体积小:采用LZ77 算法的派生算法,压缩比高。利用特殊的编码方法标记重复出现的数据,对图像颜色无影响。
LZ77算法是一种算法理论,而非具体代码实践。JPG 对图像亮度无影响, 压缩的是图像颜色中的蓝色和红色。
支持透明效果:对原图像定义256个透明层次, 消除锯齿边缘。GIF和JPG没有。
PNG32 支持透明效果, 剩下的两种PNG 类型也是不支持透明效果的。
索引彩色模式:采用8位调色板将RGB彩色图像转换为索引彩色图像。图像中保存的是颜色编号,每一编号对应一种颜色,图像的数据量也因此减少。
这就是群哥讲解的重点。JPG 图像中保存的是各个像素的彩色信息。
3.类型(3种)
PNG n数字n代表n bits , 表示使用2^n 大小来存储有一张图片的颜色种类, 即能存储2^n 种颜色。适用于存储颜色种类少的图片。
PNG8: 能存储256 种颜色。适用于存储颜色种类少的图片。
PNG24: 数字24代表3*8bits, 分别表示 R(红)、G(绿)、B(蓝), 能存储16777216 种颜色。
PNG32: 在PNG24的基础上增加了透明颜色, A(透明), 能存储16777216 种透明的颜色。
4.数据结构
它由一个8字节的PNG文件署名域(或理解为 header)以及3个以上的chunk组成。
如果你把PNG理解为HTTP请求, 那PNG文件署名域就是 header .
首先, 先来思考一下为什么有 「PNG文件署名域」?
PNG文件署名域的作用:识别该文件是不是PNG 文件。
该域的值为89504e470d0a1a0a(十六进制),(13780787113102610十进制),第一个字节0x89超出ASCII字符的范围,是为了避免被当做文本文件来处理。
所以,小结论:PNG 文件总是以89504e470d0a1a0a开头。
其次,为什么我要强调是「3个以上的chunk」?
最基础的PNG 文件包含IHDR、IDAT、IEND三个chunk。
每个 chunk 由4部