什么是PNG
PNG的全稱叫便攜式網絡圖型(Portable Network Graphics)是目前最流行的網絡傳輸和展示的圖片格式,原因有如下幾點:
無損壓縮:PNG圖片采取了基於LZ77派生算法對文件進行壓縮,使得它壓縮比率更高,生成的文件體積更小,並且不損失數據。
體積小:它利用特殊的編碼方法標記重復出現的數據,使得同樣格式的圖片,PNG圖片文件的體積更小。網絡通訊中因受帶寬制約,在保證圖片清晰、逼真的前提下,優先選擇PNG格式的圖片。
支持透明效果:PNG支持對原圖像定義256個透明層次,使得圖像的邊緣能與任何背景平滑融合,這種功能是GIF和JPEG沒有的。
PNG類型
PNG圖片主要有三個類型,分別為 PNG 8/ PNG 24 / PNG 32。
PNG8:PNG 8中的8,其實指的是8bits(一個字節),相當於用2^8(2的8次方)大小來存儲一張圖片的顏色種類,2^8等於256,也就是說PNG 8能存儲256種顏色,一張圖片如果顏色種類很少,將它設置成PNG 8得圖片類型是非常適合的。
PNG24:PNG 24中的24,相當於3乘以8 等於 24,就是用三個8bits分別去表示 R(紅)、G(綠)、B(藍)。R(0~255),G(0~255),B(0~255),可以表達256乘以256乘以256=16777216種顏色的圖片,這樣PNG 24就能比PNG 8表示色彩更豐富的圖片。但是所占用的空間相對就更大了。
PNG32:PNG 32中的32,相當於PNG 24 加上 8bits的透明顏色通道,就相當於R(紅)、G(綠)、B(藍)、A(透明)。R(0~255),G(0~255),B(0~255),A(0~255)。比PNG 24多了一個A(透明),也就是說PNG 32能表示跟PNG 24一樣多的色彩,並且還支持256種透明的顏色,能表示更加豐富的圖片顏色類型。
PNG圖片數據結構
PNG圖片的數據結構其實跟http請求的結構很像,都是一個數據頭,后面跟着很多的數據塊,如下圖所示:
如果你用vim的查看編碼模式打開一張png圖片,會是下面這個樣子:
這一堆十六進制編碼的含義:
89504e470d0a1a0a:這個是PNG圖片的頭,所有的PNG圖片的頭都是這一串編碼,圖片軟件通過這串編碼判定這個文件是不是PNG格式的圖片。
0000000d:是iHDR數據塊的長度,為13。
49484452:是數據塊的type,為IHDR,之后緊跟着是data。
000002bc:是圖片的寬度。
000003a5:是高度。
以此類推,每一段十六進制編碼就代表着一個特定的含義。下面其他的就不一一分析了,太多了,小伙伴們自己去查吧。
什么樣的PNG圖片更適合壓縮
常規的png圖片,顏色越單一,顏色值越少,壓縮率就越大,比如下面這張圖:
它僅僅由紅色和綠色構成,如果用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圖片如下:
這張圖片是一個紅色逐漸增強的漸變色圖,它的紅色從左到右逐漸加強,映射成數組的值為[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格式前后對比效果如下圖所示:
可以看到,導出web格式,去除了很多無用信息后,圖片明顯小了很多。
摘抄自:https://mp.weixin.qq.com/s/stvemQVmIYDu8XyyHZ-zBA