PNG

行動式網路圖形（Portable Network Graphics，PNG）是一種支援無失真壓縮的點陣圖圖形格式，支援索引、灰度、RGB 三種顏色方案以及 Alpha 通道等特性。PNG 的開發目標是改善並取代 GIF 作為適合網路傳輸的格式而不需專利許可，所以受廣泛應用於網際網路及其他方面上。

PNG 另一個非正式的名稱來源為遞迴縮寫：“PNG is Not GIF”。PNG 的官方念法是 “平”（英語 IPA：；「平」是以國語發音），但是多數人是當成三個英文字母分開讀。

PNG 圖片大多數都使用作為副檔名，其網際網路媒體型別為 image/png。PNG 於 1997 年 3 月作為知識性 RFC 2083 釋出，於 2004 年作為 ISO/IEC 標準釋出。

特性

支援 256 色調色盤技術以產生小體積檔案
最高支援 24 位真彩色影像以及 8 位灰度影像。
支援 Alpha 通道的透明 / 半透明特性。
支援影像亮度的 Gamma 校準資訊。
支援儲存附加文字資訊，以保留影像名稱、作者、版權、創作時間、註釋等資訊。
支援無失真壓縮。
漸近顯示和流式讀寫，適合在網路傳輸中快速顯示預覽效果後再展示全貌。
使用 CRC 防止檔案出錯。
最新的 PNG 標準允許在一個檔案記憶體儲多幅影像。

版本及歷史

1995 年早期，Unisys 公司根據它在 GIF 格式中使用的 LZW 資料壓縮演算法的軟體專利（ 美國 第 4558302 號）開始商業收費。為避免專利影響，用於表現單張影像的 PNG、用於表現動畫的 Multiple-image Network Graphics 圖形檔案格式同時創建出來。1999 年 8 月，Unisys 公司進一步中止了對自由軟體和非商用軟體開發者的 GIF 專利免費許可，從而使 PNG 格式獲得了更多的關注。

在 PNG 傳播過程中，很多網路瀏覽器經過很長時間才開始完全支援 PNG 格式；如 Microsoft Windows 預設的 Internet Explorer 瀏覽器一直到 7.0 版才支援 PNG 格式中的半透明效果，較早期的版本（如 6.0 SP1）需要下載 Hotfix 或由網站提供額外的 Script 去支援。這造成 PNG 格式並沒有得到廣泛的認知。

PNG 的 1.0 版本規範於 1996 年 7 月 1 日釋出，後來稱為 RFC 2083 標準，並在 1996 年 10 月 1 日成為 W3C 建議。
PNG 的 1.1 版本進行了部分小幅修改並增加了三個新的資料塊定義，於 1998 年 12 月 31 日釋出。
PNG 的 1.2 版本增加了另外一個數據塊，於 1999 年 8 月 11 日釋出。
PNG 現行版本是國際標準（ISO／IEC 15948:2003），並在 2003 年 11 月 10 日作為 W3C 建議釋出。這個版本與 1.2 版僅有細微差別。

此外也產生了基於 PNG 的動畫格式：1996 年 6 月提出 PNF（Portable Network Frame）草案，當年 8 月改名為 MNG（Multiple-image Network Graphics），但由於較為複雜，實現支援的軟體較少。2004 年末，PNG 的動畫擴充套件 ——APNG 出現。這是一個相對於 MNG 更簡單的動畫實現方案，不識別 APNG 格式的 PNG 解碼器至少能夠正常回放第一幅普通 PNG 畫面，相反地得到大部分顯示或編輯的軟體支援。

檔案結構

3.1 儲存型別

PNG 圖片主要由三種型別儲存

PNG 8：圖片使用 8 bits 來儲存，可以用 2 的 8 次方大小個種類顏色來儲存一張黑白的圖片。也就是說 PNG 8 能儲存 256 種顏色，因為顏色少，檔案體積也非常小，一張圖片如果顏色簡單，將它設定成 PNG 8 的圖片是非常省空間合適的。
PNG 24：圖片使用 24bits 來儲存，用三個 8bits 分別去表示 R（紅）、G（綠）、B（藍）三個通道（Channel）的數值。可以表達 256 乘以 256 乘以 256=16777216 種顏色的圖片，色彩豐富度更高，但相對的所佔用的空間也就更大了。
PNG 32：圖片使用 32bits 來儲存，相當於 PNG 24 加上 8bits 的透明顏色通道，總共有 R（紅）、G（綠）、B（藍）、A（透明）四個通道。圖片能表示的色彩跟 PNG 24 一樣多，並且還支援 256 種透明度，能讓圖片色彩更加豐富。

3.2 檔案資料構成

PNG 影像格式檔案由一個 8 位元組的 PNG 檔案標識（file signature or file header）域和 3 個以上的後續資料塊 (chunk) 如：IHDR、IDAT、IEND 等組成。

PNG 檔案包括 8 位元組檔案署名（89 50 4E 47 0D 0A 1A 0A，十六進位制），用來識別 PNG 格式，所有 PNG 圖片檔案內容開頭都會有這一串 header。

PNG 定義了兩種型別的資料塊：一種是 PNG 檔案必須包含、讀寫軟體也都必須要支援的關鍵塊（critical chunk）；另一種叫做輔助塊（ancillary chunks），PNG 允許軟體忽略它不認識的附加塊。這種基於資料塊的設計，允許 PNG 格式在擴充套件時仍能保持與舊版本相容。

3.2.1 資料塊結構

PNG 檔案中，每個資料塊都由四個部分組成，如下:

關鍵資料塊中有 4 個標準資料塊：

檔案頭資料塊 IHDR（header chunk）：包含有影像基本資訊，作為第一個資料塊出現並只出現一次。
調色盤資料塊 PLTE（palette chunk）：必須放在影像資料塊之前。
影像資料塊 IDAT（image data chunk）：儲存實際影像資料。PNG 資料允許包含多個連續的影像資料塊。
影像結束資料 IEND（image trailer chunk）：放在檔案尾部，表示 PNG 資料流結束。

其餘輔助資料塊列表:

壓縮方式

PNG 圖片的壓縮主要分有兩個階段：

預解析
壓縮

由於壓縮方式主要由以上兩個階段構成，最佳化方向也對應著兩個階段。針對預解析階段做最佳化主要的選擇是去最佳化差分編碼器，讓編碼出的結果能出現盡可能多的零值或是相同的值。針對壓縮階段的最佳化則是找出更好的 Deflate 演算法，以獲得更高的壓縮率。

4.1 預解析

在這階段中，圖片會做先做些預處理，以利後續壓縮。 每次會處理圖片中某一行的資料，首先經過濾波器 來處理這些資料，每個畫素點在不同通道中（ ex:RGB）的數值都會經過濾波器運算，然就得出的結果會交由差分處理器來重新計算通道中的數值。 差分處理器會將目前這個畫素點上通道中的數值和之前或之上（EX：左邊上方）畫素點做對比，根據差異進行差分編碼。若是相鄰的畫素點在通道上的數值非常接近，就會得出很多 1,0,-1 這種很小的值。 整個 prediction 階段要做的事就是找到適合的差分編碼器，使得最終差分編碼的結果盡可能的都是重複很小或是零的值，這一階段的結果會影響到 Compression 階段中能實現的壓縮率。

4.2 壓縮

經過預解析階段之後，將編碼出的結果輸出給 Deflate（是一種無損資料壓縮演算法，同時使用了 LZ77 和 Huffman Coding 方法），由其執行真正的壓縮操作，在此階段會透過 LZ77 和 Huffman Coding 方法來對影像進行編碼，最後將處理後的圖片結果儲存。最終的壓縮率主要受到兩方面的影響:

預解析階段的處理結果：對於 RGB 通道數值相近的畫素區域，也就是編碼結果有很多零值的區域，在壓縮階段得當的壓縮率會特別高，若是相鄰區域的顏色差異大，則壓縮效果就會大打折扣。
Deflate 每一行的匹配情形：在整個壓縮處理過程中都是以行為單位來進行處理。而在處裡資料的過程中，處裡的符號數被限制在 3－258 之間，換言之，最高的壓縮率可以達到 1032:1，當出現的符號數小於 3 時，就可能會出現無法匹配的情況。因此圖片的寬度也會是一個可能影響最終壓縮效果的因素之一。

4.3 壓縮方案

PNG 壓縮提供兩種壓縮方案

無失真壓縮：資料經過壓縮之後，資訊不受損失，能夠完全還原至壓縮前的模樣，通常此種壓縮方案的壓縮率有一定的限制。
有失真壓縮：資料經過壓縮之後，資訊資料會和原始資料不同，但僅限於些微差距，通常此種壓縮方案能提供非常高的壓縮率。

4.3.1 無失真壓縮方案

目前大部分 PNG 的壓縮採用基於 LZ77 派生演算法，使得它壓縮比率更高，生成的檔案體積更小，並且不損失資料。

4.3.2 有失真壓縮方案

由於 PNG 原本的無失真壓縮方案在壓縮率上有一定的限制，有些開源者無法接受既有的壓縮率，因此基於 PNG 原本的壓縮方式開發新的有失真壓縮方案，在工程上與得到了一定的應用。例如 TinyPNG, 根據官方公開的資訊，其利用了 Quantization 的技術來實現提高壓縮率，透過合併相似的顏色將 24 位元的 PNG 圖片壓縮成更小的 8 位元圖片。其中更著名的 PNG 有失真壓縮演算法 pngquant，在 Github 上有完整的開原始碼，同樣也是使用了 Vector Quantization 來減少圖片中顏色的種類，在向量化過程中將畫素點根據顏色相似程度進行分組，隨後組內的畫素統計出一個中心顏色並將所有組內畫素都替代為此中心顏色。向量化會造成圖片失真，如何在壓縮率與圖片質量之間取得一個恰到好處的平衡點是個值得最佳化的方向。