我正在嘗試撰寫代碼來讀取 BMP 檔案,因此我正在嘗試讀取 BMP 標頭。我正在使用來自某個代碼庫的測驗影像,但看起來該結構與 Wikipedia Wikipedia BMP structure上有關 BMP 影像結構的資訊不對應,尤其是部分應存盤偏移量的位置(“偏移量,即開始地址,可以找到位圖影像資料(像素陣列)的位元組。”)在維基百科的表格中作為影像的開頭如下所示:
00000000: 424d ea88 0000 0000 0000 3604 0000 2800 BM........6...(.
00000010: 0000 e300 0000 9500 0000 0100 0800 0000 ................
00000020: 0000 0000 0000 0000 0000 0000 0000 0001 ................
00000030: 0000 0000 0000 2c2a 2c00 4c8f 6900 252e ......,*,.L.i.%.
00000040: 9900 385b 4700 4c54 9700 98c9 a000 7a8c ..8[G.LT......z.
所以很明顯,影像從 36h 開始,而不是 436h,根據維基百科應該看起來像 - 在我看來,有效資訊有 1 個位元組,而不是 4 個位元組。因此,我試圖找到有關標頭資訊的另一個來源,但我只找到了與上述文章中描述的資訊相同的資訊。
我以為我存盤了錯誤的影像,所以我決定通過 Gimp 打開它并將其存盤為新的,但看起來標題具有相同的結構,只是影像的開頭被移動了。
00000000: 424d 2e89 0000 0000 0000 7a04 0000 6c00 BM........z...l.
00000010: 0000 e300 0000 9500 0000 0100 0800 0000 ................
00000020: 0000 b484 0000 130b 0000 130b 0000 0001 ................
00000030: 0000 0001 0000 4247 5273 0000 0000 0000 ......BGRs......
00000040: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000060: 0000 0000 0000 0000 0000 0200 0000 0000 ................
00000070: 0000 0000 0000 0000 0000 2c2a 2c00 4c8f ..........,*,.L.
00000080: 6900 252e 9900 385b 4700 4c54 9700 98c9 i.%...8[G.LT....
因此,Gimp 不僅可以毫無問題地讀取標題,而且甚至可以創建相同型別的標題。但根據檔案,看起來二進制部分應該存盤在 436h 上,相應的 47Ah 因為應該使用很少的位元組序。我顯然在那里遺漏了一些東西,但我無法理解這一點,因為不同的來源fastgraph.com BMP 標題 docs.fileformat.com BMP 結構顯示相同的偏移量,但由于某種原因,這里的實際情況有所不同。你能把我推到這里嗎?
PS:我會在這里粘貼原始影像,但看起來影像會自動匯出為 png 格式。
uj5u.com熱心網友回復:
tl; dr:在您的影像中有一個顏色表。當有顏色表時,它位于 DIB 標頭之后,像素資料位于其后。由于顏色表從 0x36 到 0x435 運行,因此像素資料本身確實在 0x436。
上次我使用它時,關于 BMP 格式的 Wikipedia 文章是正確的,并且比大多數其他來源更全面、更好地呈現。
BMP 檔案有一個檔案頭和一個位圖資訊頭(有時稱為 DIB 頭)。像素資料可能會在資訊標頭之后立即開始,但可能會有額外的顏色資訊和/或填充。像素資料在那之后。
根據您的第一個十六進制轉儲,您正確的是檔案頭說像素資料從 0x0436 開始。您沒有顯示足夠多的檔案來查看像素資料是否實際上從 0x0436 開始,但我們可以檢查 DIB 標頭以查看它是否一致。
DIB 標頭更復雜,因為有很多版本。從偏移量 0x0E 開始,我們可以讀取到 DIB 標頭的大小為 0x28(或十進制的 40)。這告訴我們這是香草BITMAPINFOHEADER。
位圖大小為 227x149 像素。(小心,因為奇怪的寬度可能很難得到恰到好處。)
像素格式為每像素 8 位,BI_RGB 為壓縮值。所以在標題之后和像素資料之前會有一個顏色表(調色板)。事實上,標題明確表示將有 256 個顏色表條目。
所以顏色表從 0x36 開始。顏色表中的每個條目是四個位元組(RGBQUAD),因此表長度為 256 色 * 4 位元組/顏色 = 1024 位元組。因此該表從 0x36 運行到 0x435。
像素資料可以位于顏色表之后的任何位置,只要它與 4 位元組邊界對齊即可。由于 0x0436 是 4 的倍數,因此這是第一個可能的可用地址。這也正是檔案標題所說的像素資料所在的位置。
(當您使用 Gimp 保存影像時,Gimp 選擇使用 0x6C 位元組長的位圖資訊標頭的不同版本來保存它,并且它使用不同的像素格式,因此像素資料以更大的偏移量開始也就不足為奇了。)
uj5u.com熱心網友回復:
感謝所有回復!
在所有回應之后,看起來我做錯了,因為我認為位圖調色板的開始是影像的開始,因為開始的顏色看起來像影像第一個像素中的顏色。所有回復都對我有用,因為它們幫助我更好地理解了這個話題。在閱讀了 Martin Rosenau 的評論后,這有助于我理解我的錯誤,這對http://libertybasicuniversity.com/lbnews/nl100/format.htm文章也很有幫助。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/459726.html
上一篇:什么是PSP(程式段前綴)?
