PNG

圖像文件的無損壓縮文件格式系列

可攜式網絡圖形(英語:Portable Network GraphicsPNG)是一種支援無損壓縮點陣圖圖形格式,支援索引、灰度RGB三種顏色方案以及Alpha通道等特性。PNG的開發目標是改善並取代GIF作為適合網絡傳輸的格式而不需專利許可,所以受廣泛應用於互聯網及其他方面上。

可攜式網絡圖形
Portable Network Graphics

透明的8位元PNG圖片
副檔名
.png
網路媒體型式
image/png
類型代碼英語Type code
  • PNG
  • PNGf
統一類型標識public.png
開發者W3C
首次發佈1996年10月1日,​28年前​(1996-10-01
格式類型無損壓縮
延伸為
標準
免費格式?

PNG另一個非正式的名稱來源為遞歸縮寫:「PNG is Not GIF」。PNG的官方念法是「平」(英語IPA:/pɪŋ/;「平」是以國語發音),[1]但是多數人是當成三個英文字母分開讀。[2]

PNG圖片大多數都使用PNG作為副檔名,其互聯網媒體類型image/png[3]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 [4]或由網站提供額外的Script去支援。[5]這造成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現行版本是國際標準(ISOIEC 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畫面,相反地得到大部分顯示或編輯的軟件支援。

檔案結構

儲存型別

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種透明度,能讓圖片色彩更加豐富。

檔案資料構成

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。

十六進制 含義
89 用於檢測傳輸系統是否支援8位元的字元編碼(8 bit data),用以減少將文字檔案被錯誤的辨識成PNG檔案的機會,反之亦然。
50 4E 47 PNG每個字母對應的ASCII,讓用戶可以使用文字編輯器檢視時,辨識出是PNG檔案。
0D 0A DOS風格的換行符(CRLF)。用於DOS-Unix數據的換行符轉換。
1A 在DOS命令列下,用於阻止檔案顯示的檔案結束符。
0A Unix風格的換行符(LF)。用於Unix-DOS換行符的轉換。

PNG定義了兩種類型的數據塊:一種是PNG檔案必須包含、讀寫軟件也都必須要支援的關鍵塊(critical chunk);另一種叫做輔助塊(ancillary chunks),PNG允許軟件忽略它不認識的附加塊。這種基於數據塊的設計,允許PNG格式在擴充時仍能保持與舊版本相容

數據塊結構

PNG檔案中,每個數據塊都由四個部分組成,如下:

名稱 位元組數 說明
長度(Length) 4位元組 指定數據塊中數據區域的長度,長度不可超過(231-1)個位元組
數據塊類型碼(Chunk Type Code) 4位元組 數據塊類型碼由ASCII字母(A-Z和a-z)組成的"數據塊符號"
數據塊數據(Chunk Data) 可變長度 儲存數據塊類型碼指定的數據
循環冗餘檢測(CRC) 4位元組 儲存用來檢測是否檔案傳輸有誤的循環冗餘碼

關鍵數據塊中有4個標準數據塊:

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

其餘輔助數據塊列表:

數據塊識別符號 數據塊含意 數據塊位置限制
cHRM 基色和白色點數據塊 放在PLTE和IDAT之前
gAMA 圖像γ數據塊 放在PLTE和IDAT之前
sBIT 樣本有效位數據塊 放在PLTE和IDAT之前
bKGD 背景顏色數據塊 放在PLTE之後IDAT之前
hIST 圖像直方圖數據塊 放在PLTE之後IDAT之前
tRNS 圖像透明數據塊 放在PLTE之後IDAT之前
pHYs 物理像素尺寸數據塊 放在IDAT之前
tIME 圖像最後修改時間數據塊 無限制
tEXt 檔案基本訊息數據塊 無限制
zTXt 壓縮文字數據塊 無限制
eXIf Exif數據塊 放在IHDR和IEND之間,

但不能在IDAT塊之間

sCAL (專用公共數據塊) 放在IDAT之前
oFFs (專用公共數據塊) 放在IDAT之前
fRAc (專用公共數據塊) 無限制
gIFg (專用公共數據塊) 無限制
gIFt (專用公共數據塊) 無限制
gIFx (專用公共數據塊) 無限制

壓縮方式

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

  • 預解析(Prediction
  • 壓縮(Compression

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

預解析

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

壓縮

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

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

壓縮方案

PNG壓縮提供兩種壓縮方案

  • 無損壓縮(Lossless Compression):數據經過壓縮之後,資訊不受損失,能夠完全還原至壓縮前的模樣,通常此種壓縮方案的壓縮率有一定的限制。
  • 有損壓縮(Lossy compression):數據經過壓縮之後,資訊數據會和原始數據不同,但僅限於些微差距,通常此種壓縮方案能提供非常高的壓縮率。

無損壓縮方案

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

有損壓縮方案

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

與其他格式相比

與GIF相比

  • 一般情況下將靜態GIF圖像無失真轉換為PNG後可以壓縮率會略為提高(前提是同樣採用8位元索引模式)。
  • PNG可提供更大顏色深度的支援,包括24位元(8位元3通道)和48位元(16位元3通道)真彩色。加入Alpha通道後可進一步支援每像素64位元的表示。
  • 超過8位元色深的PNG圖像轉換為GIF時,圖像質素會由於分色(顏色數減少)而下降。
  • GIF原生支援動態圖像,PNG只能通過非標準實現,在PNG的基礎上另有發展出支援動畫的APNGMNG格式,但目前普及度不高。

PNG在IE6等舊代瀏覽器上的支援較差。

與JPEG相比

JPEG可以對相片(或類似)圖像生成更小的檔案,這是由於JPEG採用了一種針對相片圖像的特定有損編碼方法,這種編碼適用於低對比,圖像顏色過渡平滑,雜訊多,且結構不規則的情況下。如果在這種情況下用PNG代替JPEG,檔案尺寸增大很多,而圖像質素的提高有限。相應的,如果儲存文字,線條或類似的邊緣清晰,有大塊相同顏色區域的圖像,PNG格式的壓縮效果就要比JPEG好很多,並且不會出現JPEG那樣的高對比度區域的圖像失真。如果圖像既有清晰邊緣,又有相片圖像的特點,就需要在這兩種格式之間權衡一下了。JPEG不支援透明度。

由於JPEG是失真壓縮,會產生迭代失真,在重複壓縮和解碼的過程中會不斷遺失資訊使圖像質素下降。由於PNG是無失真的,儲存將要編輯的圖像來說更加合適。雖然PNG壓縮相片圖像也有效,但有專門針對相片圖像設計的無損壓縮格式,例如無失真JPEG2000DNG。總的來說這些格式都不能做到適用所有圖像。對於將要發佈的圖像可以儲存成JPEG,用JPEG編碼一次不會造成明顯的圖像失真。

與JPEG-LS相比

JPEG-LS是一個「幾乎」無損壓縮格式,相對於上面提到的有損JPEG壓縮,它的知名度不高。它可以直接和PNG相比較,使用一組標準的測試圖像。在Waterloo Repertoire ColorSet(一組標準測試圖像)下,JPEG-LS通常表現要比PNG好10%-15%,但其中有一些圖像PNG表現明顯更好一些,大約50%-75%。所以,如果這兩種格式都支援而且對圖檔大小很敏感的話,可以用這兩種格式都試試,和圖像數據本身有比較大關係。

與TIFF相比

TIFF是一個相當多方案結合的格式。它廣泛用作專業圖像編輯軟件之間圖像交換的中間格式,因此它不斷支援更多應用程式所需的功能,而對應用程式不關心的圖像操作部分支援不多。這也意味着許多應用程式只能辨識TIFF的一個子集,而產生更多的潛在混淆之處。

TIFF使用的最通用的無損壓縮演算法是LZW。這種演算法在GIF中也在使用,直到2003年一直在專利保護之中。有一種TIFF變種使用與PNG相同的壓縮演算法,但是沒有獲許多專利程式所支援。TIFF也提供了一種特殊的無損壓縮演算法,類似CCITT Group IV,可以對二值圖像(比如傳真或黑白文字)比PNG有更好的壓縮效果。

PNG只支援非自左乘α,而TIFF也支援聯合(自左乘)α。

PNG規範中不包含嵌入式EXIF(可交換圖檔格式)圖像數據的標準,比如數位相機拍得的圖像。而TIFF,JPEG 2000, DNG都支援EXIF。

早期的瀏覽器不支援PNG圖像;JPEG和GIF是主流圖像格式。由於GIF的顏色深度限制,網頁中的有顏色過渡的圖像都是使用JPEG。不管怎樣,JPEG壓縮都會導致圖像的輕微模糊。而PNG可以做到在相應顏色深度下的儘可能精確,同時保持圖檔不大。PNG已經漸漸成為一種對於小的梯度圖像的較好的選擇,眾多瀏覽器都已經對PNG有了很好的支援。

參考文獻

  1. ^ History of PNG. Libpng.org. 29 May 2010 [2010-10-20]. (原始內容存檔於2004-10-16). 
  2. ^ Definition of PNG noun from the Oxford Advanced Learner's Dictionary. Oxford Learner's Dictionaries. [2018-01-21]. (原始內容存檔於2019-04-22). 
  3. ^ Registration of new Media Type image/png. IANA. 1996-07-27 [2018-01-09]. (原始內容存檔於2017-09-15). 
  4. ^ Microsoft技術支援服務 - You cannot view some PNG images in Internet Explorer 6頁面存檔備份,存於互聯網檔案館),於2009年6月1日查閱。
  5. ^ The PNG problem in Windows Internet Explorer頁面存檔備份,存於互聯網檔案館),於2009年6月1日查閱。

外部連結