<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    PNG文件結構分析 ---Png解析

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接 PNG文件結構分析 ---Png解析  

     

    為了實現更高級的應用,我們必須充分挖掘PNG的潛力。

    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文件結構應該如下:   PNG文件標志 PNG數據塊 …… PNG數據塊

     

    PNG數據塊(Chunk)

    PNG定義了兩種類型的數據塊,一種是稱為關鍵數據塊(critical chunk),這是標準的數據塊,另一種叫做輔助數據塊(ancillary chunks),這是可選的數據塊。關鍵數據塊定義了4個標準數據塊,每個PNG文件都必須包含它們,PNG讀寫軟件也都必須要支持這些數據塊。雖然PNG文件規范沒有要求PNG編譯碼器對可選數據塊進行編碼和譯碼,但規范提倡支持可選數據塊。

    下表就是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個部分組成,如下:

    名稱 字節數 說明 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

    CRC: 一種校驗算法。僅僅用來校驗數據的正確性的

     

    下面,我們依次來了解一下各個關鍵數據塊的結構吧。

     

    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圖片的要求:
    • 在MIDP1.0中,只可以使用1.0版本的PNG圖片。
    • 文件大小:MIDP支持任意大小的PNG圖片,然而實際上,如果一個圖片過大,會由于內存耗盡而無法讀取。
    • 顏色類型:所有顏色類型都有被支持,雖然這些顏色的顯示依賴于實際設備的顯示能力。同時,MIDP也能支持alpha通道,但是,所有的alpha通道信息都會被忽略并且當作不透明的顏色對待。
    • 色深:所有的色深都能被支持。
    • 壓縮方法:僅支持deflate壓縮方式,這和jar文件的壓縮方式完全相同,所以,PNG圖片數據的解壓和jar文件的解壓可以使用相同的代碼。
    • 濾波器方法:在PNG中所有的5種方法都被支持。
    • 隔行掃描:雖然MIDP支持0、1兩種方式,然而,當使用隔行掃描時,MIDP卻不會真正的使用隔行掃描方式來顯示。
    • PLTE chunk:支持
    • IDAT chunk:圖像信息必須使用5種過濾方式中的方式之一 (None, Sub, Up, Average, Paeth)
    • IEND chunk:當IEND數據塊被找到時,這個PNG圖像才認為是合法的PNG圖像。
    • 可選數據塊:MIDP可以支持下列輔助數據塊,然而,這卻不是必須的。
    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開始編號,然后是1、2……,調色板的顏色數不能超過色深中規定的顏色數(如圖像色深為4的時候,調色板中的顏色數不可以超過2^4=16),否則,這將導致PNG圖像不合法。 真彩色圖像和帶alpha通道數據的真彩色圖像也可以有調色板數據塊,目的是便于非真彩色顯示程序用它來量化圖像數據,從而顯示該圖像。   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 以下是由Fireworks生成的一幅圖像,圖像大小為8*8, 為了方便觀看,將圖像放大:

    使用UltraEdit32打開該文件,如下:
    00000000~00000007:
    可以看到,選中的頭8個字節即為PNG文件的標識。 接下來的地方就是IHDR數據塊了: 00000008~00000020:
    • 00 00 00 0D 說明IHDR頭塊長為13
    • 49 48 44 52 IHDR標識
    • 00 00 00 08 圖像的寬,8像素
    • 00 00 00 08 圖像的高,8像素
    • 04 色深,2^4=16,即這是一個16色的圖像(也有可能顏色數不超過16,當然,如果顏色數不超過8,用03表示更合適)
    • 03 顏色類型,索引圖像
    • 00 PNG Spec規定此處總為0(非0值為將來使用更好的壓縮方法預留),表示使壓縮方法(LZ77派生算法)
    • 00 同上
    • 00 非隔行掃描
    • 36 21 A3 B8 CRC校驗
    00000021~0000002F: 可選數據塊sBIT,顏色采樣率,RGB都是256(2^8=256) 00000030~00000062: 這里是調色板信息
    • 00 00 00 27 說明調色板數據長為39字節,既13個顏色數
    • 50 4C 54 45 PLTE標識
    • FF FF 00 顏色0
    • FF ED 00 顏色1
    • …… ……
    • 09 00 B2 最后一個顏色,12
    • 5F F5 BB DD CRC校驗
    00000063~000000C5: 這部分包含了pHYs、tExt兩種類型的數據塊共3塊,由于并不太重要,因此也不再詳細描述了。

    000000C0~000000F8:
    以上選中部分是IDAT數據塊
    • 00 00 00 27 數據長為39字節
    • 49 44 41 54 IDAT標識
    • 78 9C…… 壓縮的數據,LZ77派生壓縮方法
    • DA 12 06 A5 CRC校驗
    IDAT中壓縮數據部分在后面會有詳細的介紹。 000000F9~00000104: IEND數據塊,這部分正如上所說,通常都應該是 00 00 00 00 49 45 4E 44 AE 42 60 82 至此,我們已經能夠從一個PNG文件中識別出各個數據塊了。由于PNG中規定除關鍵數據塊外,其它的輔助數據塊都為可選部分,因此,有了這個標準后,我們可以通過刪除所有的輔助數據塊來減少PNG文件的大小。(當然,需要注意的是,PNG格式可以保存圖像中的層、文字等信息,一旦刪除了這些輔助數據塊后,圖像將失去原來的可編輯性。) 刪除了輔助數據塊后的PNG文件,現在文件大小為147字節,原文件大小為261字節,文件大小減少后,并不影響圖像的內容。
    • 如上說過,IDAT數據塊是使用了LZ77壓縮算法生成的,由于受限于手機處理器

     

     

    其實,我們可以通過改變調色板的色值來完成一些又趣的事情,比如說實現云彩/水波的流動效果,實現圖像的淡入淡出效果等等

    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全