?? png文件結構分析.htm
字號:
<TD><STRONG>留言板</STRONG></TD></TR>
<TR>
<TD>
<DIV align=left>
<DIV align=left>
<DIV
id=newmessage></DIV></DIV></DIV></TD></TR></TBODY></TABLE><BR>
<TABLE height=36 width="95%" border=0>
<TBODY>
<TR>
<TD><STRONG>鏈接</STRONG></TD></TR>
<TR>
<TD height=15>
<DIV align=left>
<DIV id=links></DIV>
<SCRIPT
src="PNG文件結構分析_files/ad_userlinksjs.htm"></SCRIPT>
</DIV></TD></TR></TBODY></TABLE><BR>
<TABLE width="95%" border=0>
<TBODY>
<TR>
<TD><STRONG>Blog信息</STRONG></TD></TR>
<TR>
<TD>
<DIV align=left>
<DIV id=info></DIV></DIV></TD></TR></TBODY></TABLE>
<P align=center>
<DIV id=xml><A
href="http://www.gissky.net/blog/user1/997/rss2.xml"
target=_blank><IMG height=14 src="PNG文件結構分析_files/xml.gif"
width=36 border=0></A></DIV><BR>
<P></P>
<DIV align=center></DIV>
<DIV align=center><BR></DIV></TD></TR></TBODY></TABLE></TD>
<TD vAlign=top align=middle>
<TABLE style="TABLE-LAYOUT: fixed; WORD-BREAK: break-all"
cellSpacing=1 cellPadding=3 width="98%" bgColor=#cccccc border=0>
<TBODY>
<TR bgColor=#f8f8f8>
<TD><FONT size=4><STRONG><IMG
src="PNG文件結構分析_files/1.gif">PNG文件結構分析</STRONG></FONT><BR>dn
發表于 2005-4-21 9:36:03 </TD></TR>
<TR bgColor=#ffffff>
<TD height=0>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><STRONG>前言</STRONG>
<P>PNG是20世紀90年代中期開始開發的圖像文件存儲格式,其目的是企圖替代GIF和TIFF文件格式,同時增加一些GIF文件格式所不具備的特性。流式網絡圖形格式(Portable
Network Graphic Format,PNG)名稱來源于非官方的“PNG's Not
GIF”,是一種位圖文件(bitmap
file)存儲格式,讀成“ping”。PNG用來存儲灰度圖像時,灰度圖像的深度可多到16位,存儲彩色圖像時,彩色圖像的深度可多到48位,并且還可存儲多到16位的α通道數據。PNG使用從LZ77派生的無損數據壓縮算法。</P>
<P><STRONG>PNG數據塊(Chunk)</STRONG></P>
<P>PNG定義了兩種類型的數據塊,一種是稱為關鍵數據塊(critical
chunk),這是標準的數據塊,另一種叫做輔助數據塊(ancillary
chunks),這是可選的數據塊。關鍵數據塊定義了4個標準數據塊,每個PNG文件都必須包含它們,PNG讀寫軟件也都必須要支持這些數據塊。雖然PNG文件規范沒有要求PNG編譯碼器對可選數據塊進行編碼和譯碼,但規范提倡支持可選數據塊。</P>
<P>下表就是PNG中數據塊的類別,其中,關鍵數據塊部分我們使用深色背景加以區分。</P>
<TABLE class=text cellSpacing=1 cellPadding=3
align=center bgColor=#000000 border=0>
<TBODY>
<TR bgColor=#ffffff>
<TD colSpan=5>
<DIV
align=center><STRONG>PNG文件格式中的數據塊</STRONG></DIV></TD></TR>
<TR bgColor=#ffffff>
<TD>
<DIV align=center><B>數據塊符號</B></DIV></TD>
<TD>
<DIV align=center><B>數據塊名稱 </B></DIV></TD>
<TD>
<DIV align=center><B>多數據塊 </B></DIV></TD>
<TD>
<DIV align=center><B>可選否 </B></DIV></TD>
<TD>
<DIV align=center><B>位置限制 </B></DIV></TD></TR>
<TR bgColor=#cccccc>
<TD>IHDR </TD>
<TD>文件頭數據塊 </TD>
<TD>否 </TD>
<TD>否 </TD>
<TD>第一塊 </TD></TR>
<TR bgColor=#ffffff>
<TD>cHRM </TD>
<TD>基色和白色點數據塊 </TD>
<TD>否 </TD>
<TD>是</TD>
<TD>在PLTE和IDAT之前</TD></TR>
<TR bgColor=#ffffff>
<TD>gAMA </TD>
<TD>圖像γ數據塊 </TD>
<TD>否 </TD>
<TD>是</TD>
<TD>在PLTE和IDAT之前 </TD></TR>
<TR bgColor=#ffffff>
<TD>sBIT </TD>
<TD>樣本有效位數據塊 </TD>
<TD>否 </TD>
<TD>是</TD>
<TD>在PLTE和IDAT之前 </TD></TR>
<TR bgColor=#cccccc>
<TD>PLTE </TD>
<TD>調色板數據塊 </TD>
<TD>否 </TD>
<TD>是</TD>
<TD>在IDAT之前 </TD></TR>
<TR bgColor=#ffffff>
<TD>bKGD </TD>
<TD>背景顏色數據塊 </TD>
<TD>否 </TD>
<TD>是</TD>
<TD>在PLTE之后IDAT之前 </TD></TR>
<TR bgColor=#ffffff>
<TD>hIST </TD>
<TD>圖像直方圖數據塊 </TD>
<TD>否 </TD>
<TD>是</TD>
<TD>在PLTE之后IDAT之前 </TD></TR>
<TR bgColor=#ffffff>
<TD>tRNS </TD>
<TD>圖像透明數據塊 </TD>
<TD>否 </TD>
<TD>是</TD>
<TD>在PLTE之后IDAT之前 </TD></TR>
<TR bgColor=#ffffff>
<TD>oFFs </TD>
<TD>(專用公共數據塊) </TD>
<TD>否 </TD>
<TD>是</TD>
<TD>在IDAT之前 </TD></TR>
<TR bgColor=#ffffff>
<TD>pHYs </TD>
<TD>物理像素尺寸數據塊 </TD>
<TD>否 </TD>
<TD>是</TD>
<TD>在IDAT之前 </TD></TR>
<TR bgColor=#ffffff>
<TD>sCAL </TD>
<TD>(專用公共數據塊) </TD>
<TD>否 </TD>
<TD>是</TD>
<TD>在IDAT之前 </TD></TR>
<TR bgColor=#cccccc>
<TD>IDAT </TD>
<TD>圖像數據塊 </TD>
<TD>是</TD>
<TD>否 </TD>
<TD>與其他IDAT連續</TD></TR>
<TR bgColor=#ffffff>
<TD>tIME </TD>
<TD>圖像最后修改時間數據塊 </TD>
<TD>否 </TD>
<TD>是</TD>
<TD>無限制 </TD></TR>
<TR bgColor=#ffffff>
<TD>tEXt </TD>
<TD>文本信息數據塊 </TD>
<TD>是</TD>
<TD>是</TD>
<TD>無限制 </TD></TR>
<TR bgColor=#ffffff>
<TD>zTXt </TD>
<TD>壓縮文本數據塊 </TD>
<TD>是</TD>
<TD>是</TD>
<TD>無限制 </TD></TR>
<TR bgColor=#ffffff>
<TD>fRAc </TD>
<TD>(專用公共數據塊) </TD>
<TD>是</TD>
<TD>是</TD>
<TD>無限制 </TD></TR>
<TR bgColor=#ffffff>
<TD>gIFg </TD>
<TD>(專用公共數據塊) </TD>
<TD>是</TD>
<TD>是</TD>
<TD>無限制 </TD></TR>
<TR bgColor=#ffffff>
<TD>gIFt </TD>
<TD>(專用公共數據塊) </TD>
<TD>是</TD>
<TD>是</TD>
<TD class=text>無限制 </TD></TR>
<TR bgColor=#ffffff>
<TD>gIFx </TD>
<TD>(專用公共數據塊) </TD>
<TD>是</TD>
<TD>是</TD>
<TD>無限制 </TD></TR>
<TR bgColor=#cccccc>
<TD>IEND </TD>
<TD>圖像結束數據 </TD>
<TD>否 </TD>
<TD>否 </TD>
<TD>最后一個數據塊 </TD></TR></TBODY></TABLE>
<P>為了簡單起見,我們假設在我們使用的PNG文件中,這4個數據塊按以上先后順序進行存儲,并且都只出現一次。</P>
<P><STRONG>數據塊結構</STRONG></P>
<P>PNG文件中,每個數據塊由4個部分組成,如下:</P>
<TABLE class=text cellSpacing=1 cellPadding=3
align=center bgColor=#000000 border=0>
<TBODY>
<TR bgColor=#ffffff>
<TD><B>名稱 </B></TD>
<TD><B>字節數 </B></TD>
<TD><B>說明 </B></TD></TR>
<TR bgColor=#ffffff>
<TD>Length (長度) </TD>
<TD>4字節 </TD>
<TD>指定數據塊中數據域的長度,其長度不超過(2<SUP>31</SUP>-1)字節 </TD></TR>
<TR bgColor=#ffffff>
<TD>Chunk Type Code (數據塊類型碼) </TD>
<TD>4字節 </TD>
<TD>數據塊類型碼由ASCII字母(A-Z和a-z)組成 </TD></TR>
<TR bgColor=#ffffff>
<TD>Chunk Data (數據塊數據) </TD>
<TD>可變長度 </TD>
<TD>存儲按照Chunk Type Code指定的數據 </TD></TR>
<TR bgColor=#ffffff>
<TD>CRC (循環冗余檢測) </TD>
<TD>4字節 </TD>
<TD>存儲用來檢測是否有錯誤的循環冗余碼 </TD></TR></TBODY></TABLE>
<P>CRC(cyclic redundancy check)域中的值是對Chunk Type
Code域和Chunk Data域中的數據進行計算得到的。CRC具體算法定義在ISO 3309和ITU-T
V.42中,其值按下面的CRC碼生成多項式進行計算:</P>
<P>x<SUP>32</SUP>+x<SUP>26</SUP>+x<SUP>23</SUP>+x<SUP>22</SUP>+x<SUP>16</SUP>+x<SUP>12</SUP>+x<SUP>11</SUP>+x<SUP>10</SUP>+x<SUP>8</SUP>+x<SUP>7</SUP>+x<SUP>5</SUP>+x<SUP>4</SUP>+x<SUP>2</SUP>+x+1</P>
<P>下面,我們依次來了解一下各個關鍵數據塊的結構吧。</P>
<P><STRONG>IHDR</STRONG></P>
<P>文件頭數據塊IHDR(header
chunk):它包含有PNG文件中存儲的圖像數據的基本信息,并要作為第一個數據塊出現在PNG數據流中,而且一個PNG數據流中只能有一個文件頭數據塊。</P>
<P>文件頭數據塊由13字節組成,它的格式如下表所示。</P>
<TABLE class=text cellSpacing=1 cellPadding=3
align=center bgColor=#000000 border=0>
<TBODY>
<TR bgColor=#ffffff>
<TD>
<DIV align=center><B>域的名稱 </B></DIV></TD>
<TD>
<DIV align=center><B>字節數 </B></DIV></TD>
<TD>
<DIV align=center><B>說明 </B></DIV></TD></TR>
<TR bgColor=#ffffff>
<TD>Width </TD>
<TD>4 bytes </TD>
<TD>圖像寬度,以像素為單位 </TD></TR>
<TR bgColor=#ffffff>
<TD>Height </TD>
<TD>4 bytes </TD>
<TD>圖像高度,以像素為單位 </TD></TR>
<TR bgColor=#ffffff>
<TD>Bit depth </TD>
<TD>1 byte </TD>
<TD>圖像深度: <BR>索引彩色圖像:1,2,4或8 <BR>灰度圖像:1,2,4,8或16
<BR>真彩色圖像:8或16 </TD></TR>
<TR bgColor=#ffffff>
<TD>ColorType </TD>
<TD>1 byte </TD>
<TD>顏色類型:<BR>0:灰度圖像, 1,2,4,8或16 <BR>2:真彩色圖像,8或16
<BR>3:索引彩色圖像,1,2,4或8 <BR>4:帶α通道數據的灰度圖像,8或16
<BR>6:帶α通道數據的真彩色圖像,8或16 </TD></TR>
<TR bgColor=#ffffff>
<TD>Compression method </TD>
<TD>1 byte </TD>
<TD>壓縮方法(LZ77派生算法) </TD></TR>
<TR bgColor=#ffffff>
<TD>Filter method </TD>
<TD>1 byte </TD>
<TD>濾波器方法 </TD></TR>
<TR bgColor=#ffffff>
<TD>Interlace method </TD>
<TD>1 byte </TD>
<TD>隔行掃描方法:<BR>0:非隔行掃描 <BR>1: Adam7(由Adam M.
Costello開發的7遍隔行掃描方法) </TD></TR></TBODY></TABLE>
<P>由于我們研究的是手機上的PNG,因此,首先我們看看MIDP1.0對所使用PNG圖片的要求吧:</P>
<UL>
<LI>在MIDP1.0中,我們只可以使用1.0版本的PNG圖片。并且,所以的PNG關鍵數據塊都有特別要求:<BR>IHDR
<LI>文件大小:MIDP支持任意大小的PNG圖片,然而,實際上,如果一個圖片過大,會由于內存耗盡而無法讀取。
<LI>顏色類型:所有顏色類型都有被支持,雖然這些顏色的顯示依賴于實際設備的顯示能力。同時,MIDP也能支持alpha通道,但是,所有的alpha通道信息都會被忽略并且當作不透明的顏色對待。
<LI>色深:所有的色深都能被支持。
<LI>壓縮方法:僅支持壓縮方式0(deflate壓縮方式),這和jar文件的壓縮方式完全相同,所以,PNG圖片數據的解壓和jar文件的解壓可以使用相同的代碼。(其實這也就是為什么J2ME能很好的支持PNG圖像的原因:))
<LI>濾波器方法:盡管在PNG的白皮書中僅定義了方法0,然而所有的5種方法都被支持!
<LI>隔行掃描:雖然MIDP支持0、1兩種方式,然而,當使用隔行掃描時,MIDP卻不會真正的使用隔行掃描方式來顯示。
<LI>PLTE chunk:支持
<LI>IDAT chunk:圖像信息必須使用5種過濾方式中的方式0 (None, Sub, Up,
Average, Paeth)
<LI>IEND chunk:當IEND數據塊被找到時,這個PNG圖像才認為是合法的PNG圖像。
<LI>可選數據塊:MIDP可以支持下列輔助數據塊,然而,這卻不是必須的。
<BLOCKQUOTE>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -