当前位置 - 股票行情交易網 - 財經資訊 - 便攜式網絡圖形(PNG)規範(第二版)

便攜式網絡圖形(PNG)規範(第二版)

2003年11月10日W3C正式推薦

當前版本: work byte order)。

而現在的主機壹般使用的 X86、ARM 處理器都是小端模式,被稱為主機字節順序(host byte order)。

PNG 使用網絡字節順序。

普通的真彩圖片,至少由紅、綠、藍三個通道組成,也就是每個像素占用了三個字節以上的空間。這樣圖片的壓縮效率就很低。

因此,我們構建壹個調色板,在調色板裏預設好我們需要使用到的顏色,後續使用時,只需要提供調色板的索引位置就可以了。

而且為了防止調色板占用過大空間,我們把調色板的容量設定在256以內。索引位置也就不會超過256,只需要壹個字節就可以表示,壹個字節只占用壹個通道,因此索引模式下,只有壹個通道。

壹個圖片是由許多像素點組成的,可以視作壹個二維數組。我們可以提取其中幾個特殊的位置,比如橫行每隔壹個提取壹個像素,豎列每隔壹個提取壹個像素,這樣組成壹個新的二維數組,可以簡略失真的表示原圖。這種提取方法叫做 Pass 提取(pass extraction),提取之後形成的數據是交錯的,每段都可以包含整個圖片的縮略部分。只需要重新組合就能產生完整的圖像,即使沒有完整的數據,只要其中壹部分就可以得到縮略圖。是網絡傳輸中加快圖像傳輸的方式,不過現在網速很快,幾乎用不到了。

色圖的中間區域是白色的,被我們稱作白點,是色圖的壹個參數。另壹個參數是基準,用作色圖的平移。

我們可以設置白點的坐標,來改變中間白色區域,使其向紅色、綠色、藍色偏移,用以調整色圖的變化程度。

PNG 規範不指定應用程序接口,但是涉及四種圖像:原圖、標準圖像、PNG 圖像、交付圖像。關系如下:

二進制編碼占用的比特數,就是樣本深度。

PNG 有三種管理色彩空間的方法:使用 ICC 配置、使用 sRGB 配置、使用色度基準和白點位置配置。

ICC 配置比較靈活,易於適配;sRGB 配置需要設置壹個特定的顏色空間,可能會占用較多的容量;最後壹種比較精確。前兩種也推薦使用伽馬值。

我們需要通過壹些手段,將標準圖像轉換為 PNG 圖像。流程如下:

分離透明通道,實際上,很多標準圖像沒有透明通道,這樣可以默認為無透明度,節省壹個通道。

如果不同像素值的個數少於 256,樣本深度小於等於8,可以開始構建索引。

如果,顏色樣本深度壹致,而且每個通道都壹樣的值,可以用壹個通道來表示所有,即灰度圖。

不用 alpha 通道表示透明度的壹種方法,需要設置背景色。

不是所有的深度都被 PNG 支持,只有 1、2、4、8、16,如果不是這些數的話,深度就要通過軟件調節。

比如原始深度是 5,現在要把它變成 8,也就是擴大了。

如果不同通道有不同的深度,我們就會選取最大深度來調整。

這種深度變換是可逆的。

壹***有五種:

這裏采用兩種方法進行 Pass 提取。

第壹種是空方法,也就是什麽都不做。(所以為什麽要這麽死板的把這個也計作壹種方法)

第二種通過多次掃描得到七個縮小圖。也就是 Adam7 算法(不是深度學習的那個 Adam 算法)。

不過這個算法在國內網站這個幾乎找不到,維基百科 https://en.wikipedia.org/wiki/Adam7_algorithm )介紹的也不是很清楚。所以我這裏就簡單說壹下:

把上面的到的縮小圖(當然空方法讀出來的是原圖),逐行再讀取壹遍。(這裏的操作就可以有很多了,比如把上面的提取變成壹個 yield)

有幾種過濾類型,會把過濾類型寫到過濾數組之前。

就是編碼加密。

把編碼後的數據分成壹塊或者多塊。

壹個標準的 PNG 文件由許多塊組成,每個塊有四個部分:長度、名稱、數據主體、校驗碼。

標準的 PNG 定義有 18 種塊類型,此外妳可以添加自定義的各種塊。

這 18 種塊類型有:

關鍵塊:

IHDR(image header 文件頭)、PLTE(palette 調色板)、IDAT(image data 圖片內容)、IEND(image end 文件結尾)

輔助塊:

透明相關:tRNS(transparency information 透明信息)

顏色相關:cHRM(chromaticities and white point 色度和白點)、gAMA(gamma 伽馬值)、iCCP(embedded ICC profile 嵌入式 ICC 概述)、sBIT(significant bits 有效位)、sRGB(standard RGB colour space 標準RGB顏色空間)

文本相關:iTXt(international textual data 國際化文本)、tEXt(textual data 文本)、zTXt(zip textual data 壓縮的文本)

時間相關:tIME(last-modification time 最新修改時間)

其他:bKGD(background colour 背景色)、hIST(histogram 直方圖)、pHYs(physical pixel dimensions 物理像素尺寸)、sPLT(Suggested palette 建議調色板)、

傳輸錯誤或文件損壞,這會破壞數據流的大部分或全部;語法錯誤,出現無效塊或者丟失塊。

兩種錯誤處理方式要區別。

妳可以向 ISO/IEC 或者 PNG Group 提交相關擴展,註冊新的塊類型和文本關鍵字,拓展新的過濾算法、交錯模式的算法、壓縮算法。

就是數據流的二進制的結構啦。

所有 PNG 數據流的前八個字符,都是 137 80 78 78 71 13 10 26 10

用 bytes 表示就是 b'\x89PNG\r\n\x1a\n'

這個簽名表示接下來的數據都是 PNG 數據流,如果遇到空字符不要打斷,需要出現 IEND 才算結束。

每個塊由這四個部分組成:

通過名稱約定,使得 PNG 解碼器在不能識別當前塊的用途時,也能通過名稱來獲取相關信息。

塊的名稱有四位:

第壹位表示輔助,小寫表示這個塊是輔助塊,大寫表示這個塊是關鍵塊。

第二位表示私有,小寫表示這個塊是私有的,而非國際標準定義的,大小表示前述 18 種塊類型。

第三位是保留位,小寫表示這個塊是被拋棄的,大寫表示可以使用。(用於約定將來的擴展)

第四位表示復制安全性,也就是 PNG 編輯器在編輯圖片的時候,如果遇到不安全的數據塊,就不會完全的復制,而是有選擇的,大寫表示 PNG 編輯器可以完全的復制,而不需要擔心任何問題。

具體參考 crc32 算法

因為 PNG 圖像是可以流式讀取的,也就是說不需要讀到文件尾,就可以在 PNG 瀏覽器裏預覽了。

所以有些東西需要在讀取圖像內容之前準備好,比如索引調色板。

好像在 4.3 章節寫過了?

我們在 4.4 章寫過,有五種顏色類型:

顏色類型記錄在 IHDR 裏。

灰度模式下,亮度取決於 gAMA、sRGB、iCCP,如果沒有這些,則取決於機器。

顏色樣本不壹定和光強成正比,可以通過設置 gAMA 來調節。

值的計算方法如下: 初始為 0,使用了調色板加上1,使用了真彩加上2,使用了透明通道加上4。灰度下是無法使用索引。

有四種方式表示透明:使用透明通道、使用 tRNS 塊設置透明顏色信息、索引中在 tRNS 設置 alpha 表、不使用透明通道也不使用 tRNS 表示完全不透明。

透明通道的樣本深度是 8 和 16,透明通道保存在像素之中, 表示完全透明, 表示完全不透明。透明度用於圖像前景色和背景色的復合。

壹些普通的圖片不包含透明度,甚至已經把像素值乘以透明度,提前做好了以黑色為背景的復合步驟;但是 PNG 不這麽做。

整形(int)是多位字節,short 是兩個,int 是四個,long 是八個。

PNG 使用的是網絡字節順序,MSB 在高位,LSB 在低位。

也就是每個 PNG 圖像的行,緊湊排列各個像素。

深度少於 8 時,掃描線結尾可能是湊不齊字節,這些不使用的字節不進行處理。

濾波器可以提高壓縮數據的壓縮性,而且是可逆的。PNG 允許過濾掃描線數據,換句話說就是可以不進行濾波。

過濾後的字節序列與過濾前的相同,但是根據不同的濾波類型,會在最前面添加壹個字節的標記。如果沒有增加長度就表明沒有過濾過。具體過濾方法,在後面解釋。

交錯模式可以提高 CRT 顯示器上網絡圖片的加載速度(換句話,沒有網絡,沒有 CRT 顯示器,交錯模式就沒有用了)。

參考[4.5.2 Pass 提取](#4.5.2 Pass 提取)

介於 Adam7 的特點,寬或者高小於5的圖像會缺少縮略圖(2在第五列,3在第五行)。

過濾的目的在於提高壓縮率。過濾的方法不是唯壹的,交錯模式下,所有縮小圖都應該使用同壹種方法的濾波器;非交錯模式下,只有壹張圖,當然也是只有壹種方法。

這個標準裏定義了壹種 0 號方法,其他的編號為將來保留。0 號方法包含五種類型的濾波器,每個掃描線可以使用不同的濾波器類型。

PNG 規範不強制濾波器的類型,具體的選擇方法後面在說。

濾波器是針對字節的,和像素、通道、深度無關。只要給字節就能過濾。

這裏是幾個參數的定義:

Org() 表示字節原始值;

Flt() 表示過濾後的值;

Rc() 表示重構的值;

Paeth() 參見[9.4 濾波器類型4](#9.4 濾波器類型4)。

如果沒有前壹個像素,就用 0 代替。每個縮小圖的第壹行沒有前壹行,也用 0 代替。

因為使用了過濾,重建時也要按照這個順序進行計算。

濾波器的輸入輸出值都是無符號字節。

0、1、2 三種類型的濾波器都很簡單,隔列/隔行相減就是。

但是第三種類型, Flt(x) = Org(x) - floor((Org(a) + Org(b)) / 2) 中, Org(a) + Org(b) 存在溢出的情況,不能使用 byte 運算,應該是 short 或者更多位,當然也有右移的算法。

Paeth 算法先計算三個相鄰像素(左、上、左上)的線性值,選擇與計算值最接近的相鄰像素再次計算。註意緩存不要溢出。它的函數如下:

與上面的過濾壹樣,默認的就是 0 號方法。這兩個在 IHDR 裏面有標記。

當然,這裏用的是 zlib 的壓縮,使用默認的等級為 8,壓縮字節不超過 32768。

這個校驗值和 PNG 塊的校驗值不壹樣,兩者不能混同。

多個過濾後的行,會被打包壓縮成壹個 zlib 數據流,並放到多個 PNG 塊裏,多個 PNG 塊解開得到的是壹個 zlib 數據流。

當然,這個還涉及到異步讀取。zlib 數據流本身就是可以中斷的,即使中斷,排列較前的數據還是可以讀取出來的,這樣才有交錯模式的解讀,所以針對上面的 python 方法,有如下改進:

構建壹個持續的讀取,邊讀取邊解析。

下面是 18 個 PNG 規範塊的介紹:

IHDR 是 PNG 數據流中的第壹個塊。組成如下:

所以 IHDR 塊長度是 13 不會改變。

調色板是壹個二維數組,可以看作 Array[n][3],用索引 n 來表示顏色。

因此,n 不會超過 256,PLTE 塊的長度也是 3 的倍數。

調色板無論如何都是 8 位深度,即使圖像是 1、2、4 的深度,調色板也還是 8。

所有的 IDAT 塊合起來是壹個 zlib 數據流,參考[10 壓縮](#10 壓縮)。

這段數據是空的,表示 PNG 數據流結束了。當然,這個塊損壞也不會有事。

這是表示透明度信息的塊,有三種構成:

灰度模式(凡是等於這個灰度的顏色被認做透明)

真彩模式(由這三個值表示壹個透明色)

索引模式(索引模式下,tRNS 相當於壹個 alpha 表,這個表和索引壹樣大,對應表示索引的透明度)

為什麽灰度模式和真彩模式用 2 字節表示呢,因為需要適配 16 位深度,而索引模式深度永遠小於等於 8。

這個塊用於設置壹個 CIE 色度空間。組成如下:

儲存值是實際值的 100000 倍。

CIE 色度空間是壹個二維圖像,它由紅綠藍白四個點構建壹個近視三角形的包圍圈,來設置顏色的偏移程度。

這個塊只儲存了壹個 unsigned int,同樣的它的值需要除以 100000,得到實際的 gamma 值。

這個塊用於設置壹個 ICC 描述。

PNG 只支持固定的深度,如果原圖深度不匹配,就會強制的放縮,但是原始信息會保留在這裏,用於恢復原始圖像。(所以壹般不會用到,為什麽要把標準圖像轉化成非標準圖像呢)

針對不同通道數,有不同的 sBIT 長度。

使用 sRGB 色彩空間,這時候不能用 ICC 描述了。sRGB 只包含有壹個 unsigned byte,表示渲染意圖。

值的意義如下:

使用 sRGB 時,推薦使用 gAMA、cHRM,因為有些設備不支持 sRGB,這樣就可以兼容性使用。

上面是壹個文本信息會使用到的關鍵字,關鍵字其實不是很關鍵,就是壹個定義而已,可以自己改動。但是符合上述的是可以被圖像軟件標準讀取。

tEXt 含有如下成分:

當然,這裏的壓縮方法也是 0,用 zlib 解壓後面的數據

國際文本數據,有點高大上的感覺。

語言種類參見 RCF-3066、ISO 646、ISO 639。

背景色哦。

直方圖給出了調色板中每種顏色的近似使用頻率。

如果 PNG 瀏覽器無法提供調色板裏所有的顏色,那麽直方圖可以輔助創建相似的調色板供使用。

當然,現在不存在不能提供完整的調色板的軟件了。

這個塊用於表示像素在屏幕上的實際尺寸。結構如下:

單位說明有兩個,False 的時候表示這個塊只表示長寬的比,而不是真實值;True 的時候以米為單位,即壹個單位為壹米,壹米包含多少個像素。

具體的通道長度,由樣本深度決定,深度為 16 就是兩個,小於等於 8 就是壹個。

調色板名稱是區分大小寫的,並受到與關鍵字參數相同的限制。

在灰度PNG圖像中,每個目通常相等的紅色、綠色、藍色和藍色值,但這不是必需的。

每壹個頻率值與圖像的像素的比例成正比,不是實際頻率。

這裏用宇宙時間(Universal Time,UTC)

後面的公式太復雜了,算了,直