2014-10-19 73 views
3

看着PNG specification,看起來PNG像素數據塊開始於IDAT並以IEND結束(稍微更清晰的解釋here)。在中間是對我來說沒有意義的價值觀。解釋PNG像素數據

如何從這裏獲得可用的RGB值,而無需使用任何庫(即從原始二進制文件)?

作爲一個例子,我在Photoshop與4個黑色rgb(0,0,0)像素由2x2px圖像:
Just four black pixels...

這裏的所得到的數據(在原始二進制輸入,則十六進制值,和人類可讀的ASCII) :

BINARY  HEX ASCII 
01001001 49 'I' 
01000100 44 'D' 
01000001 41 'A' 
01010100 54 'T' 
01111000 78 'x' 
11011010 DA '\xda' 
01100010 62 'b' 
01100000 60 '`' 
01000000 40 '@' 
00000110 06 '\x06' 
00000000 00 '\x00' 
00000000 00 '\x00' 
00000000 00 '\x00' 
00000000 00 '\x00' 
11111111 FF '\xff' 
11111111 FF '\xff' 
00000011 03 '\x03' 
00000000 00 '\x00' 
00000000 00 '\x00' 
00001110 0E '\x0e' 
00000000 00 '\x00' 
00000001 01 '\x01' 
10000011 83 '\x83' 
11010100 D4 '\xd4' 
11101100 EC '\xec' 
10001110 8E '\x8e' 
00000000 00 '\x00' 
00000000 00 '\x00' 
00000000 00 '\x00' 
00000000 00 '\x00' 
01001001 49 'I' 
01000101 45 'E' 
01001110 4E 'N' 
01000100 44 'D' 

回答

6

你錯過了在這兩個規格相當關鍵的細節:

官方之一:

.. IDAT塊包含實際的圖像數據,它是壓縮算法的輸出流。
[...]
PNG內的減壓數據流以「zlib」格式存儲。

百科:

IDAT包含圖像,其可以在多個組塊IDAT之間進行分割。這種分割會稍微增加文件大小,但可以以流式方式生成PNG。 IDAT塊包含實際的圖像數據,這是壓縮算法的輸出流。

這兩種狀態的原始圖像數據是壓縮。看着你的數據,前2個字節

78 DA 

包含在RFC1950指定的壓縮標誌。其餘數據被壓縮。

與一般zlib兼容例程解壓顯示這14個字節的輸出:

00 00 00 00 00 00 00 
00 00 00 00 00 00 00 

,其中每個第一個字節是PNG行過濾器(0爲兩行),然後是2 RGB三元(0,0 ,0),爲您的圖像的2行。

「沒有使用任何庫」你需要3個獨立的程序來:

  1. 讀和解析PNG上層建築;這提供了壓縮數據以及基本信息,例如寬度,高度和顏色深度;
  2. zlib零件解壓縮爲原始二進制數據;
  3. 解析解壓縮的數據,如果需要處理Adam-7隔行掃描,並應用行過濾器。

只有在執行這三個步驟後,您才能訪問原始圖像數據。其中,您似乎對步驟(1)有很好的掌握。步驟(2)更難以「自己動手」;個人而言,我欺騙並在我自己的PNG處理程序中使用了miniz。步驟3再一次只是確定的問題。所有必要的信息都可以在網上找到,但需要一段時間才能將所有信息按照正確的順序排列。 (就在最近,我在很少使用Paeth行篩選器的執行中發現的錯誤 - 因爲這是相當罕見的「真實世界」的圖像用它去注意。)

了類似的討論和Trying to understand zlib/deflate in PNG filesBuilding a fast PNG encoder issues深入瞭解Deflate方案。

+0

非常非常有幫助 - 謝謝! – JeffThompson 2014-10-20 11:25:40