天天看點

PNG編解碼算法詳解1.PNG介紹2.PNG檔案解析2.PNG檔案解析3.Filter4.deflate5.png格式怎麼用參考

1.PNG介紹

PNG是便攜式網絡圖型( Portable Network Graphics)的縮寫,由于PNG帶有透明通道,無損壓縮,可提升設計元素的呈現效果,是以設計上對PNG情有獨鐘,廣泛的運用在設計、遊戲、網頁、app開發裡,實際使用上由于存在很多誤區,導緻被濫用,這裡對之前學習png的心得做個整理。

首先,PNG和誕生跟GIF格式有較大關系,這中間有很多趣事,可自行查閱。PNG的壓縮過程是完全無損的,壓縮過的檔案可以準确的還原出原圖,可封裝多種pixfmt格式的資料,并且是一種可擴充的封裝格式,

PNG檔案格式裡面包含不同的區塊(chunks),各個區塊帶有不同類型的資料。典型的PNG資料包括四部分,而在此基礎上,增加acTL(動畫控制塊)、fcTL(幀控制塊)、fdAT(幀資料塊)即為APNG動圖格式。

  • PNG Signature(PNG簽名塊,包含PNG類型的辨別)
  • IHDR(圖像頭部塊,包含圖檔的寬度、高度、位的深度和顔色類型)
  • IDAT(圖像資料塊,像素壓縮後的資料)
  • IEND(圖像結束塊,PNG結束辨別)

2.PNG檔案解析

PNG圖像格式檔案由一個8位元組的PNG檔案署名(PNG signature:0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A)和按照特定結構組織的3個以上的資料(chunk)組成。PNG定義了兩種類型的資料塊,一種是稱為關鍵資料塊(critical chunk),這是标準的資料塊,另一種叫做輔助資料塊(ancillary chunks),這是可選的資料塊。關鍵資料塊定義了4個标準資料塊,每個PNG檔案都必須包含它們,PNG讀寫軟體也都必須要支援這些資料塊,雖然PNG檔案規範沒有要求PNG編解碼器對可選資料塊進行編碼和解碼,但規範提倡支援可選資料塊。

PNG編解碼算法詳解1.PNG介紹2.PNG檔案解析2.PNG檔案解析3.Filter4.deflate5.png格式怎麼用參考

2.PNG檔案解析

PNG圖像格式檔案由一個8位元組的PNG檔案署名(PNG signature:0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A)和按照特定結構組織的3個以上的資料(chunk)組成。PNG定義了兩種類型的資料塊,一種是稱為關鍵資料塊(critical chunk),這是标準的資料塊,另一種叫做輔助資料塊(ancillary chunks),這是可選的資料塊。關鍵資料塊定義了4個标準資料塊,每個PNG檔案都必須包含它們,PNG讀寫軟體也都必須要支援這些資料塊,雖然PNG檔案規範沒有要求PNG編解碼器對可選資料塊進行編碼和解碼,但規範提倡支援可選資料塊。

PNG編解碼算法詳解1.PNG介紹2.PNG檔案解析2.PNG檔案解析3.Filter4.deflate5.png格式怎麼用參考

每個資料塊按如下方式排列,包括資料塊 内 資料長度、塊類型、塊資料和CRC校驗碼。

PNG編解碼算法詳解1.PNG介紹2.PNG檔案解析2.PNG檔案解析3.Filter4.deflate5.png格式怎麼用參考

一個典型的PNG檔案的十六進制如下:

PNG編解碼算法詳解1.PNG介紹2.PNG檔案解析2.PNG檔案解析3.Filter4.deflate5.png格式怎麼用參考
PNG編解碼算法詳解1.PNG介紹2.PNG檔案解析2.PNG檔案解析3.Filter4.deflate5.png格式怎麼用參考

(1)PNG signature

PNG signature為固定的8個位元組0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A

(2)IHDR

檔案頭資料塊IHDR(header chunk,13個位元組)包含PNG檔案中存儲的圖像資料的基本資訊,包括分辨率、比特深度、色彩模式、壓縮方法,是非常重要的資料塊,必須作為第一個資料塊出現在PNG資料流中,而且一個PNG資料流中隻能有一個檔案頭資料塊。

PNG編解碼算法詳解1.PNG介紹2.PNG檔案解析2.PNG檔案解析3.Filter4.deflate5.png格式怎麼用參考

(3)IDAT

圖像資料塊IDAT(image data chunk)存儲實際的資料,在資料流中可包含多個連續順序的圖像資料塊。IDAT存放着圖像真正的資料資訊,是以,如果能夠了解IDAT的結構,我們就可以很友善的生成PNG圖像。

生成IDAT需要先經過Filter(具體算法由IHDR指定),再經過Deflate(具體算法由IHDR指定)

(4)IEND

圖像結束資料IEND(image trailer chunk)用來标記PNG檔案或者資料流已經結束,并且必須要放在檔案的尾部。如果我們仔細觀察PNG檔案,我們會發現,檔案的結尾12個字元看起來總應該是這樣的:00 00 00 00 49 45 4E 44 AE 42 60 82

由于IEND資料塊的長度是0(00 00 00 00,除非人為加入資訊),資料辨別總是IEND(49 45 4E 44),是以,CRC碼也總是AE 42 60 82。

3.Filter

IDAT的壓縮過程主要包括Filter和deflate兩部分,Filter即對像素做過濾,PNG編碼使用差分對原始像素資料進行Filter,該過程無任何壓縮損失,并且完全可逆。對圖像來說,存儲殘差所需的比特遠遠小于實際圖像所需,這也是差分編碼的收益來源。

PNG編解碼算法詳解1.PNG介紹2.PNG檔案解析2.PNG檔案解析3.Filter4.deflate5.png格式怎麼用參考

差分編碼原理如下,對于每一行像素點X,使用左、左上、上的三個像素來進行限制,對于不同的内容,須使用不同的Filter類型來提升壓縮收益。

PNG編解碼算法詳解1.PNG介紹2.PNG檔案解析2.PNG檔案解析3.Filter4.deflate5.png格式怎麼用參考

PNG在壓縮時,對每行的圖像以byte為機關進行filter,如圖像為真彩色RGBA圖像,則先對R分量進行filter,再依次對G、B、A進行Filter[5]。

4.deflate

PNG中的Deflate與gzip、zlib中的deflate原理一樣,結合了LZ77和Hoffman算法。

Ziv和Lempel于1977年發表《A Universal Algorithm for Sequential Data Compression 》進行像素資料的壓縮,定義了一種編碼标準而沒定義具體實作,後來稱為LZ77算法,LZ77壓縮算法采用字典的方式進行壓縮,是一個簡單但十分高效的資料壓縮算法。其方式就是把資料中一些可以組織成短語(最長字元)的字元加入字典,然後再有相同字元出現采用标記來代替字典中的短語,如此通過标記代替多數重複出現的方式以進行壓縮。Hoffman是一種變長編碼,即用少的bit數表示出現機率大的資料。

deflate算法用在壓縮圖檔資料上,有以下特點:

  • Deflate算法隻能比對3到258個之間符号,是以最大的壓縮比隻能到1035:1;
  • 如果比對到的符号小于3,那麼你會産生一些額外的開銷來表示這些符号;

    上面的這兩點意味着實際圖檔大小會受到每一行像素的比對程度影響。

5.png格式怎麼用

對于PNG格式資料,實際項目應用上,選擇很多,可以用opencv,也可以用libpng這種原生開源庫。

後面再來介紹libpng編解碼的實作及調用。

參考

[1] http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html

[2] http://www.libpng.org/pub/png/spec/1.2/PNG-Filters.html

[3] https://blog.csdn.net/asdzheng/article/details/51476818?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

[4] https://blog.csdn.net/john_cdy/article/details/46936667

[5] http://www.libpng.org/pub/png/spec/1.2/PNG-DataRep.html#DR.Image-layout

[6] https://mp.weixin.qq.com/s/XGzuSF-L-qKriyRGcGs-KA

繼續閱讀