PNG的文件結構算法
對於一個PNG文件來講,其文件頭老是由位固定的字節來描述的:編碼
十進制數 | 137 80 78 71 13 10 26 10 |
十六進制數 | 89 50 4E 47 0D 0A 1A 0A |
其中第一個字節0x89超出了ASCII字符的範圍,這是爲了不某些軟件將PNG文件當作文本文件來處理。文件中剩餘的部分由3個以上的PNG的數據塊(Chunk)按照特定的順序組成,所以,一個標準的PNG文件結構應該以下:spa
PNG文件標誌 | PNG數據塊 | …… | PNG數據塊 |
PNG數據塊(Chunk)orm
PNG定義了兩種類型的數據塊,一種是稱爲關鍵數據塊(critical chunk),這是標準的數據塊,另外一種叫作輔助數據塊(ancillary chunks),這是可選的數據塊。關鍵數據塊定義了4個標準數據塊,每一個PNG文件都必須包含它們,PNG讀寫軟件也都必需要支持這些數據塊。雖然PNG文件規範沒有要求PNG編譯碼器對可選數據塊進行編碼和譯碼,但規範提倡支持可選數據塊。htm
下表就是PNG中數據塊的類別,其中,關鍵數據塊部分咱們使用深色背景加以區分。索引
PNG文件格式中的數據塊
|
||||
數據塊符號
|
數據塊名稱
|
多數據塊
|
可選否
|
位置限制
|
IHDR | 文件頭數據塊 | 否 | 否 | 第一塊 |
cHRM | 基色和白色點數據塊 | 否 | 是 | 在PLTE和IDAT以前 |
gAMA | 圖像γ數據塊 | 否 | 是 | 在PLTE和IDAT以前 |
sBIT | 樣本有效位數據塊 | 否 | 是 | 在PLTE和IDAT以前 |
PLTE | 調色板數據塊 | 否 | 是 | 在IDAT以前 |
bKGD | 背景顏色數據塊 | 否 | 是 | 在PLTE以後IDAT以前 |
hIST | 圖像直方圖數據塊 | 否 | 是 | 在PLTE以後IDAT以前 |
tRNS | 圖像透明數據塊 | 否 | 是 | 在PLTE以後IDAT以前 |
oFFs | (專用公共數據塊) | 否 | 是 | 在IDAT以前 |
pHYs | 物理像素尺寸數據塊 | 否 | 是 | 在IDAT以前 |
sCAL | (專用公共數據塊) | 否 | 是 | 在IDAT以前 |
IDAT | 圖像數據塊 | 是 | 否 | 與其餘IDAT連續 |
tIME | 圖像最後修改時間數據塊 | 否 | 是 | 無限制 |
tEXt | 文本信息數據塊 | 是 | 是 | 無限制 |
zTXt | 壓縮文本數據塊 | 是 | 是 | 無限制 |
fRAc | (專用公共數據塊) | 是 | 是 | 無限制 |
gIFg | (專用公共數據塊) | 是 | 是 | 無限制 |
gIFt | (專用公共數據塊) | 是 | 是 | 無限制 |
gIFx | (專用公共數據塊) | 是 | 是 | 無限制 |
IEND | 圖像結束數據 | 否 | 否 | 最後一個數據塊 |
爲了簡單起見,咱們假設在咱們使用的PNG文件中,這4個數據塊按以上前後順序進行存儲,而且都只出現一次。圖片
數據塊結構內存
PNG文件中,每一個數據塊由4個部分組成,以下:ci
名稱 | 字節數 | 說明 |
Length (長度) | 4字節 | 指定數據塊中數據域的長度,其長度不超過(231-1)字節 |
Chunk Type Code (數據塊類型碼) | 4字節 | 數據塊類型碼由ASCII字母(A-Z和a-z)組成 |
Chunk Data (數據塊數據) | 可變長度 | 存儲按照Chunk Type Code指定的數據 |
CRC (循環冗餘檢測) | 4字節 | 存儲用來檢測是否有錯誤的循環冗餘碼 |
CRC(cyclic redundancy check)域中的值是對Chunk Type Code域和Chunk Data域中的數據進行計算獲得的。CRC具體算法定義在ISO 3309和ITU-T V.42中,其值按下面的CRC碼生成多項式進行計算:開發
x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1
下面,咱們依次來了解一下各個關鍵數據塊的結構吧。
IHDR
文件頭數據塊IHDR(header chunk):它包含有PNG文件中存儲的圖像數據的基本信息,並要做爲第一個數據塊出如今PNG數據流中,並且一個PNG數據流中只能有一個文件頭數據塊。
文件頭數據塊由13字節組成,它的格式以下表所示。
域的名稱
|
字節數
|
說明
|
Width | 4 bytes | 圖像寬度,以像素爲單位 |
Height | 4 bytes | 圖像高度,以像素爲單位 |
Bit depth | 1 byte | 圖像深度: 索引彩色圖像:1,2,4或8 灰度圖像:1,2,4,8或16 真彩色圖像:8或16 |
ColorType | 1 byte | 顏色類型: 0:灰度圖像, 1,2,4,8或16 2:真彩色圖像,8或16 3:索引彩色圖像,1,2,4或8 4:帶α通道數據的灰度圖像,8或16 6:帶α通道數據的真彩色圖像,8或16 |
Compression method | 1 byte | 壓縮方法(LZ77派生算法) |
Filter method | 1 byte | 濾波器方法 |
Interlace method | 1 byte | 隔行掃描方法: 0:非隔行掃描 1: Adam7(由Adam M. Costello開發的7遍隔行掃描方法) |
因爲咱們研究的是手機上的PNG,所以,首先咱們看看MIDP1.0對所使用PNG圖片的要求吧:
bKGD cHRM gAMA hIST iCCP iTXt pHYs
sBIT sPLT sRGB tEXt tIME tRNS zTXt
PLTE
調色板數據塊PLTE(palette chunk)包含有與索引彩色圖像(indexed-color image)相關的彩色變換數據,它僅與索引彩色圖像有關,並且要放在圖像數據塊(image data chunk)以前。
PLTE數據塊是定義圖像的調色板信息,PLTE能夠包含1~256個調色板信息,每個調色板信息由3個字節組成:
顏色 |
字節 |
意義 |
Red |
1 byte |
0 = 黑色, 255 = 紅 |
Green |
1 byte |
0 = 黑色, 255 = 綠色 |
Blue |
1 byte |
0 = 黑色, 255 = 藍色 |
所以,調色板的長度應該是3的倍數,不然,這將是一個非法的調色板。
對於索引圖像,調色板信息是必須的,調色板的顏色索引從0開始編號,而後是一、2……,調色板的顏色數不能超過色深中規定的顏色數(如圖像色深爲4的時候,調色板中的顏色數不能夠超過2^4=16),不然,這將致使PNG圖像不合法。
真彩色圖像和帶α通道數據的真彩色圖像也能夠有調色板數據塊,目的是便於非真彩色顯示程序用它來量化圖像數據,從而顯示該圖像。
IDAT
圖像數據塊IDAT(image data chunk):它存儲實際的數據,在數據流中可包含多個連續順序的圖像數據塊。
IDAT存放着圖像真正的數據信息,所以,若是可以瞭解IDAT的結構,咱們就能夠很方便的生成PNG圖像。
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。
PNG格式說明:http://www.w3.org/TR/PNG/