一、概述
對於PNG
這種影像儲存格式,它有兩個特點:無失真壓縮和支援透明效果。
- 由於
PNG
檔案採用LZ77
演算法的派生演算法進行壓縮,其結果是獲得高的壓縮比,不損失資料。它利用特殊的編碼方法標記重複出現的資料,因而對影像的顏色沒有影響,也不可能產生顏色的損失,這樣就可以重複儲存而不降低影像質量。 PNG
可以為原影像定義256
個透明層次,使得彩色影像的邊緣能與任何背景平滑地融合,從而徹底地消除鋸齒邊緣。這種功能是GIF
和JPEG
沒有的。
今天,我們就來介紹一下PNG
的相關知識。
二、PNG 原理
2.1 PNG 檔案結構
PNG
由一個8
位元組的PNG
檔案署名域和按照特定結構組織的3
個以上的資料塊組成,其中資料塊分成兩種,關鍵資料塊和可選資料塊,關鍵數塊為如下四種:
- 檔案頭資料塊
- 調色盤資料塊
- 影像資料塊
- 影像結束資料塊
而每個資料塊由以下四個資料域組成:
- 長度
- 資料塊型別碼
- 資料塊資料
- 迴圈冗餘校驗
從上面的構成中,我們可以看到,對於使用者可見的部分,真正和展現有關就是影像資料塊中的資料塊區域,因此,我們就需要注意有沒有在別的資料塊中引入了不必要的資料,例如下面的右圖,在從Photoshop
中匯出的時候,選擇了export to web
,因此它的大小就比左圖要小很多。
2.2 PNG 格式
PNG
的格式有8/24/32
三種,稱為PNG 8/ PNG 24 / PNG 32
,其中後面的數字表示最多可以索引和儲存的顏色值。
PNG 8
支援兩種不同的透明形式,索引透明和Alpha
透明PNG 24
不支援透明PNG 32
在24
位基礎上增加了8
位透明通道,因此可展現256
級透明程度
我們應當根據圖片來選擇正確的格式,在能表示圖片中顏色的前提下,儘量選擇位數較少的PNG
格式。
2.3 PNG
壓縮原理
PNG
壓縮過程分為兩個階段:Prediction 和 Compression。
2.3.1 Prediction
在這一階段,我們每次會處理圖片中一行的資料,首先通過Filter
階段處理這一行當中每一個的畫素點中每條通道的值,也就是我們常說的ARBG
。它交由差分處理器來重新計算該通道的值。差分處理會根據這個畫素點上通道和之前或者之上畫素點對應通道值之間的差異,進行差分編碼,也就是說,如果原本相鄰畫素點之間通道的值之間很接近,那麼我們就會獲得很多的1,0,-1
這種很小的值。這裡有兩點需要注意:
- 整個
Prediction
階段的目的,也就是選擇合適的差分處理器,讓最終的編碼結果出現儘可能多的零值和重複值,這一結果將會影響到Compression
階段的壓縮率。 - 差分編碼器比較的是畫素點之間對應通道的值,而並不是整個畫素點。
2.3.2 Compression
在Prediction
處理完畢之後,再將這一轉換的結果輸出給Deflate
,Deflate
執行真正的壓縮操作,它會通過LZ77
和Huffman
對影像進行編碼,最後將處理之後的結果儲存。在Compression
階段,它最終的壓縮率會受到兩方面的影響:
- Prediction 的處理結果:對於顏色相近的區域,也就是有很多零值的區域,那麼壓縮率將會更高,而如果顏色之間差異很大,那麼壓縮效果將不盡人意。
- Deflate 每一行的匹配情況:前面我們分析過,整個處理過程是按行來處理的。而在處理每一行的資料時,
Deflate
把處理的符號數限制為3 ~ 258
,也就是說,最大的壓縮率為1032:1
,當出現符號數小於3
個時,那麼就有可能出現無法匹配的情況,因此,對於圖片寬度的改變將有可能影響最終壓縮的效果。
下面,我們對於上面描述的第二點舉一個例子,對於下面兩幅圖,右圖雖然之比左圖寬了兩個畫素,但是它的大小整整大了一倍:
我們通過下面這個工具可以觀察每個畫素點的壓縮率:在分析的結果中,深藍色表示該畫素點具有較高的壓縮率,而黃色/紅色則表示壓縮率較低,可以發現正是由於改變了圖片的大小,導致某些畫素點沒有匹配到,從而產生了一個較大的檔案。
2.3.3 程式碼表示
對於 Prediction 和 Compression 這兩個過程,可以通過下面這個程式碼來理解:
三、總結
PNG
有很多優點,並且應用廣泛,但是還是需要根據具體的場景來選用:
- 如果原始的圖片為高清的,但是不要求進行無損的壓縮,那麼可以選擇類似於
JPG
這樣的有失真壓縮 - 但是從反方面來說,如果原始圖片較為簡單,並且需要支援透明形式,那麼
PNG
要由於JPG
。
這一篇文章,介紹了PNG
相關的一些知識,目的還是讓大家對這種圖片格式有一個大概的理解,這也是我們後面分析優化的基礎。