PNG檔案頭格式解析
近來為了獲取圖片大小,有點傷腦筋,引擎庫不能再讀取檔案路徑後馬上得到圖片大小
所以無奈決定,直接通過讀取png檔案頭來獲取檔案大小,這部分,確實蛋疼,找了些資料,都不是很滿意
下面這部分內容轉自:http://www.blogjava.net/security/archive/2006/06/08/51292.html
00000000h: 89 50 4E 47 0D 0A 1A 0A00 00 00 0D49
48 44 52 ; 塒NG........IHDR
00000010h: 00 00 00 CE 00 00 00 CE 08 02 00 00 00 F9 7D AA ; ...?..?....鶀?
00000020h: 93 00 00 00 09 70 48 59 73 00 00 0A 75 00 00 0A ; ?...pHYs...u...
00000030h: 75 01 4A 25 DD FD 00 00 0C 91 49 44 41 54 78 9C ; u.J%蔟...慖DATx?
00000040h: ED 9D D9 96 DC 2A 0C 45 A9 AC FC FF 2F D7 7D 70 ; 頋贃?.E┈?/讅p
00000050h: C7 97 66 10 9A 98 CF 7E C8 EA 54 95 6D 86 83 24 ; 菞f.殬蟸汝T昺唭$
00000060h: 04 B6 3F DF EF 37 00 D0 9F 3F B3 0B 00 6E 01 52 ; .?嗩7.袩??.n.R
00000070h: 03 83 F8 3B BB 00 AB F2 F9 98 0E 47 58 92 01 A9 ; .凐;?鶚.GX??
89 50 4E 47 0D 0A 1A 0A 是PNG頭部署名域,表示這是一個PNG圖片
00 00 00 0D 描述IHDR頭部的大小
49 48 44 52 是Chunk Type Code, 這裡Chunk Type Code=IHDR
00 00 00 CE 00 00 00 CE 08 02 00 00 00 描述了Chunk Data,它是可變長度資料,00 00 00 0D 定義了長度為13個Bytes,所以,這裡,你看到是13個位元組)
F9 7D AA 93 是對IHDR的CRC校驗
緊接著下面的就是pHys資料塊,原理也是一樣
------------------------------------------------------------------------------------------------------
但是這裡還是木有檔案頭的資訊,接下來,可以參考如下:
也就是可以從IHDR中,來獲取標頭檔案資訊,這裡的IHDR,其實在開始就可以看到了
00 00 00 CE 00 00 00 CE 08 02 00 00 00 描述了Chunk
Data
也就是前面的這塊資料,前四個位元組是寬度,後四個位元組是高度,也就是此圖大小為:206 * 206
由於,暫時不需要其他資料,也就不再往下研究,直接貼上,lua獲取png檔案頭的程式碼
function hexstring2number(hexstring, len) if not len or len > 8 then return end local hexbyte = {} for i = 1, len do hexbyte[i] = string.byte(hexstring, i) end local num = tonumber(string.format("0x%x%x%x%x", hexbyte[1], hexbyte[2], hexbyte[3], hexbyte[4]), 16) return num end function get_png_size(path) local png_file = io.open(path, "rb") local data = png_file:read("*all") -- 保證png至少有37個位元組,因為包含檔案頭等起碼就超過這個數字了 if #data < 37 then return end -- 檔案頭的相關資訊請百度 local png_header_info = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52} for i = 1, #png_header_info do if (string.byte(data, i) ~= png_header_info[i]) then return end end -- 這四個位元組表示png的寬度 data = string.sub(data, #png_header_info + 1) local width = hexstring2number(data, 4) -- 這四個位元組表示png的高度 data = string.sub(data, 5) local height = hexstring2number(data, 4) return width, height end get_png_size("2.png")