圖片壓縮知識梳理(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

相關文章
相關標籤/搜索