我正在尝试编写代码来读取 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 格式。
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 字节,并且它使用不同的像素格式,因此像素数据以更大的偏移量开始也就不足为奇了。)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句