姓名:鄺念君
學(xué)號:14020150024
轉(zhuǎn)載自:http://blog.chinaunix.net/uid-20622737-id-3130430.html ,有刪節(jié)捻脖。
【嵌牛導(dǎo)讀】:在Linux編程中浸剩,免不了要對圖片文件進(jìn)行讀寫操作,那就得了
解PNG文件的儲存方式。
【嵌牛鼻子】: 文件結(jié)構(gòu) 除嘹、數(shù)據(jù)塊
【嵌牛提問】: 如何讀入PNG圖片文件?
【嵌牛正文】:
PNG的文件結(jié)構(gòu)
根據(jù)PNG文件的定義來說岸蜗,其文件頭位置總是由位固定的字節(jié)來描述的:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 十進(jìn)制數(shù) 137 80 78 71 13 10 26 10
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?十六進(jìn)制數(shù) 89 50 4E 47 0D 0A 1A 0A
其中第一個(gè)字節(jié)0x89超出了ASCII字符的范圍尉咕,這是為了避免某些軟件將PNG文件當(dāng)做文本文件來處理。文件中剩余的部分由3個(gè)以上的PNG的數(shù)據(jù)塊(Chunk)按照特定的順序組成璃岳,因此年缎,一個(gè)標(biāo)準(zhǔn)的PNG文件結(jié)構(gòu)應(yīng)該如下
PNG數(shù)據(jù)塊(Chunk)
PNG定義了兩種類型的數(shù)據(jù)塊,一種是稱為關(guān)鍵數(shù)據(jù)塊(critical chunk)铃慷,這是標(biāo)準(zhǔn)的數(shù)據(jù)塊单芜,另一種叫做輔助數(shù)據(jù)塊(ancillary chunks),這是可選的數(shù)據(jù)塊犁柜。關(guān)鍵數(shù)據(jù)塊定義了4個(gè)標(biāo)準(zhǔn)數(shù)據(jù)塊洲鸠,每個(gè)PNG文件都必須包含它們,PNG讀寫軟件也都必須要支持這些數(shù)據(jù)塊馋缅。雖然PNG文件規(guī)范沒有要求PNG編譯碼器對可選數(shù)據(jù)塊進(jìn)行編碼和譯碼坛怪,但規(guī)范提倡支持可選數(shù)據(jù)塊。
下表就是PNG中數(shù)據(jù)塊的類別股囊,其中袜匿,關(guān)鍵數(shù)據(jù)塊部分我們使用深色背景加以區(qū)分。
為了簡單起見稚疹,我們假設(shè)在我們使用的PNG文件中居灯,這4個(gè)數(shù)據(jù)塊按以上先后順序進(jìn)行存儲祭务,并且都只出現(xiàn)一次。
數(shù)據(jù)塊結(jié)構(gòu)
PNG文件中怪嫌,每個(gè)數(shù)據(jù)塊由4個(gè)部分組成义锥,如下:
CRC(cyclic redundancy check)域中的值是對Chunk Type Code域和Chunk Data域中的數(shù)據(jù)進(jìn)行計(jì)算得到的。CRC具體算法定義在ISO 3309和ITU-T V.42中岩灭,其值按下面的CRC碼生成多項(xiàng)式進(jìn)行計(jì)算:
x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1
CRC: 一種校驗(yàn)算法拌倍。僅僅用來校驗(yàn)數(shù)據(jù)的正確性的
下面,我們依次來了解一下各個(gè)關(guān)鍵數(shù)據(jù)塊的結(jié)構(gòu)吧噪径。
IHDR
文件頭數(shù)據(jù)塊IHDR(header chunk):它包含有PNG文件中存儲的圖像數(shù)據(jù)的基本信息柱恤,并要作為第一個(gè)數(shù)據(jù)塊出現(xiàn)在PNG數(shù)據(jù)流中,而且一個(gè)PNG數(shù)據(jù)流中只能有一個(gè)文件頭數(shù)據(jù)塊找爱。
文件頭數(shù)據(jù)塊由13字節(jié)組成梗顺,它的格式如下表所示。
由于本文很多設(shè)計(jì)到了PNG在手機(jī)方面的應(yīng)用车摄,因此在此提出MIDP1.0對所使用PNG圖片的要求:
在MIDP1.0中寺谤,只可以使用1.0版本的PNG圖片。
文件大兴辈ァ:MIDP支持任意大小的PNG圖片变屁,然而實(shí)際上,如果一個(gè)圖片過大意狠,會由于內(nèi)存耗盡而無法讀取粟关。
顏色類型:所有顏色類型都有被支持,雖然這些顏色的顯示依賴于實(shí)際設(shè)備的顯示能力摄职。同時(shí)誊役,MIDP也能支持alpha通道获列,但是谷市,所有的alpha通道信息都會被忽略并且當(dāng)作不透明的顏色對待。
色深:所有的色深都能被支持击孩。
壓縮方法:僅支持deflate壓縮方式迫悠,這和jar文件的壓縮方式完全相同,所以巩梢,PNG圖片數(shù)據(jù)的解壓和jar文件的解壓可以使用相同的代碼创泄。
濾波器方法:在PNG中所有的5種方法都被支持。
隔行掃描:雖然MIDP支持0括蝠、1兩種方式鞠抑,然而,當(dāng)使用隔行掃描時(shí)忌警,MIDP卻不會真正的使用隔行掃描方式來顯示搁拙。
PLTE chunk:支持
IDAT chunk:圖像信息必須使用5種過濾方式中的方式之一 (None, Sub, Up, Average, Paeth)
IEND chunk:當(dāng)IEND數(shù)據(jù)塊被找到時(shí),這個(gè)PNG圖像才認(rèn)為是合法的PNG圖像。
可選數(shù)據(jù)塊:MIDP可以支持下列輔助數(shù)據(jù)塊箕速,然而酪碘,這卻不是必須的。
bKGD cHRM gAMA hIST iCCP iTXt pHYs
sBIT sPLT sRGB tEXt tIME tRNS zTXt
PLTE
調(diào)色板數(shù)據(jù)塊PLTE(palette chunk)包含有與索引彩色圖像(indexed-color image)相關(guān)的彩色變換數(shù)據(jù)盐茎,它僅與索引彩色圖像有關(guān)兴垦,而且要放在圖像數(shù)據(jù)塊(image data chunk)之前。
PLTE數(shù)據(jù)塊是定義圖像的調(diào)色板信息字柠,PLTE可以包含1~256個(gè)調(diào)色板信息探越,每一個(gè)調(diào)色板信息由3個(gè)字節(jié)組成:
因此,調(diào)色板的長度應(yīng)該是3的倍數(shù)募谎,否則扶关,這將是一個(gè)非法的調(diào)色板。
對于索引圖像数冬,調(diào)色板信息是必須的节槐,調(diào)色板的顏色索引從0開始編號,然后是1拐纱、2……铜异,調(diào)色板的顏色數(shù)不能超過色深中規(guī)定的顏色數(shù)(如圖像色深為4的時(shí)候,調(diào)色板中的顏色數(shù)不可以超過2^4=16)秸架,否則揍庄,這將導(dǎo)致PNG圖像不合法。
真彩色圖像和帶alpha通道數(shù)據(jù)的真彩色圖像也可以有調(diào)色板數(shù)據(jù)塊东抹,目的是便于非真彩色顯示程序用它來量化圖像數(shù)據(jù)蚂子,從而顯示該圖像。
IDAT
圖像數(shù)據(jù)塊IDAT(image data chunk):它存儲實(shí)際的數(shù)據(jù)缭黔,在數(shù)據(jù)流中可包含多個(gè)連續(xù)順序的圖像數(shù)據(jù)塊食茎。
IDAT存放著圖像真正的數(shù)據(jù)信息,因此馏谨,如果能夠了解IDAT的結(jié)構(gòu)别渔,我們就可以很方便的生成PNG圖像。
IEND
圖像結(jié)束數(shù)據(jù)IEND(image trailer chunk):它用來標(biāo)記PNG文件或者數(shù)據(jù)流已經(jīng)結(jié)束惧互,并且必須要放在文件的尾部哎媚。
如果我們仔細(xì)觀察PNG文件,我們會發(fā)現(xiàn)喊儡,文件的結(jié)尾12個(gè)字符看起來總應(yīng)該是這樣的:
00 00 00 00 49 45 4E 44 AE 42 60 82
不難明白拨与,由于數(shù)據(jù)塊結(jié)構(gòu)的定義,IEND數(shù)據(jù)塊的長度總是0(00 00 00 00艾猜,除非人為加入信息)买喧,數(shù)據(jù)標(biāo)識總是IEND(49 45 4E 44)攀甚,因此,CRC碼也總是AE 42 60 82岗喉。