图片压缩知识梳理(2) 减少 PNG 大小

1、概述

在上一篇文章当中,咱们简要介绍了PNG的结构,以及PNG压缩的原理,对于压缩的各个阶段能够总结出一些优化的点:git

  • 减小原始图像的颜色种类
  • 优化差分编码器,使得通过差分编码后的图像有尽量多的零值和相同的值
  • 优化Deflate的算法,得到更高的压缩率
  • 去除PNG文件中不须要的信息

今天,咱们就来一块儿学习一些关于减少PNG文件大小的方法。github

2、减少PNG大小

2.1 使用PNG优化工具

目前,已经有不少为开发者提供的PNG优化工具,例如:算法

这些工具都针对PNG压缩的某一方面进行了优化,咱们能够根据须要选择适合的工具。bash

2.2 手动减小PNG中的颜色的种类

在咱们使用工具进行优化以前,能够先进行一些预处理,例如减小图片当中颜色的种类。之因此这么作是由于颜色的种类的个数会直接影响到整个PNG压缩过程的压缩率:工具

  • Filter阶段,减小颜色的种类可使得临近像素之间的区别变少。
  • 所以,到了Deflate阶段,就能够获得更多重复的值,那么就会得到更高的压缩率。

减小图片中的颜色的种类意味着有可能致使图片的失真,所以这一过程更多的须要人为地去干预,而不是经过工具来处理。学习

2.3 选择正确的PNG格式

在前面介绍PNG的格式时,谈到了PNG能够分为8/24/32三种类型,咱们应当根据须要选择正确的格式。gradle

例如,若是图片中没有Alpha通道,那么就应当使用PNG 24,而不是使用PNG 32。相似,若是是灰度的图片,那么应当使用PNG 8优化

2.4 使用索引格式的PNG

若是图片中的颜色种类小于256,那么就可使用索引格式的PNG。它会将这256种颜色放到调色板当中,而图片中的每一个像素则转换为调色板中颜色的坐标: ui

通过这一转换以后:

  • 每一个像素所占的位数就由32位减小到了8
  • 减小了颜色的种类,这和咱们在2.2中讨论的优势相同。

所以,若是咱们可以把颜色减小到256种如下,那么PNG的大小将会大大减小。google

2.5 对于图片中透明像素点的处理

若是图片中有彻底透明的像素点,咱们根据PNG的格式分为 索引PNG普通PNG 两部分来讨论。

2.5.1 索引 PNG

若是使用的是索引PNG,那么只须要把"透明色"看成调色板中的一个颜色就能够了。

2.5.2 普通 PNG

而若是咱们使用的是普通PNG,那么就须要注意对于这些“不可见像素点”的处理,例以下面这幅图:

表面上看来,这两幅图是同样的,可是左图却要比右图大,若是咱们去掉 Alpha通道,那么效果是下面这样:
形成它们大小之间差异的缘由就在于: 虽然左图中的某些像素点因为Alpha通道的值为0而变成透明的了,可是它们的RBG通道仍然有不相同的值,所以在 filerdeflate阶段仍然要处理这些元素,并将它们压缩。

所以,对于普通PNG图片,若是是ARGB全彩的格式,对于那些Alpha通道为0的像素点,说明它们是不可见的。那么咱们应当保证这些不可见像素点的RGB通道相同,这将可以有效减小一行当中的颜色种类,从而得到更好的压缩效果。

2.6 采用 Vector Quantization 减小图片中颜色的种类

若是图像中的颜色种类小于256,那么咱们能够把它转换为索引PNG格式,而若是图片本来的颜色大于256种,那么能够经过矢量量化的方法来建立一个索引PNG格式。

在矢量量化的过程当中,会把全部的像素基于它们之间颜色的类似程度进行分组,一个组内像素的颜色会比较接近。以后根据组内的全部颜色,计算出一个中心点颜色,组内的全部颜色会被替换成为该中心点的颜色。

在上图当中

  • 绿色的点表示原始的像素颜色
  • 蓝色的范围则表示一个分组
  • 红色的点则为根据该组中的颜色,所计算出的中心点颜色

矢量量化会经过将相近颜色替换成同一种颜色的方法,来减小图片中颜色的种类,所以有可能会使得图片失真。

咱们能够经过指定图片中最多能够容许的颜色种类个数来控制量化的效果,pngquant 就是根据这一原理实现的。

3、AAPT

aapt工具会对知足必定条件的PNG图片进行优化,然而当它和其它工具结合起来的时候,反而有可能会使得通过aapt处理后的图片从新增大。

3.1 AAPT对于PNG图片的优化

Android的资源文件是经过aapt(Android Asset Package Tool)打包到Apk文件里的,而在这一打包的过程中,会对res/drawable下的符合如下三个条件之一的图片进行优化:

状况一:图片中每一个像素点的RGB三个通道的值相同 在这种状况下,PNG会被转换成为grayscale格式,也就是每个像素仅占8bit

状况二:图片中每一个像素点的Alpha通道的值都为1,这表示该图片是彻底透明的。

状况三:图片中总的颜色种类小于256种,那么会将该图片转换成为前面提到过的索引PNG格式。

对于以上三种状况的处理,都是彻底无损的处理方式,也就是通过aapt处理后的图片和原始的图片质量相同。

3.2 使用aapt的注意点

对于现代的压缩算法而言,它们都不可能作到循环压缩。也就是说,若是你尝试去压缩一张已经被压缩过的图片,那么有可能会使得该图片变大,最好的状况也就是使得新的图片和原始图片大小相同。

所以,若是咱们已经经过别的工具对png图片进行了压缩操做,以后再经过aapt进行优化,那么有可能会使图片增大10%,若是须要解决这一问题,能够在build.gradle中禁止除了.9.png以外的图片的aapt的优化操做:

aaptOptions { 
    cruncherEnabled = false 
}
复制代码

这样,你就可使用本身的png优化工具进行优化,而不用担忧aapt的优化操做会使得图片进一步变大。

4、总结

在第二节中谈到的这六点优化点,其实它们最核心的思想就是减小图片中颜色的种类,然而减小颜色的种类就意味会致使图片的失真,所以,如何选取这一平衡点是减小PNG的难点所在。

5、参考文献

Reducing PNG file Size

相关文章
相关标签/搜索