BMP 标头应该是什么样子?

无名

我正在尝试编写代码来读取 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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

使用git的IntelliJ上的Scala:.gitignore应该是什么样子?

我的 nginx.conf 应该是什么样子来提供静态内容

React-native + mobx Index.js 应该是什么样子

svg图像的ContentType标头应该是什么

添加BMP灰度标头

在导轨上使用bootstrap-sass红宝石时,application.scss应该是什么样子

你的项目的第一个提交/分支在 git flow 中应该是什么样子的

http2 中的连接消息头应该是什么样的?

virtualenv环境的结构应该是什么样的

应该是什么样的关系?

React应该是什么样的功能

将图像转换为没有BMP标头的BMP RGB565

读取BMP文件C ++(读取BMP标头出现问题)

Page类的graphql模式定义应该是什么样的?

Travis CI查找和运行测试的Python项目结构应该是什么样的?

使用cordova应用程序,openFB中的oauthRedirectURL应该是什么样的?

“高阶可遍历”类应该是什么样?

API Gateway中的AWS Firehose PutRecordBatch的映射模板应该是什么样的?

应用程序结构应该是什么样的?

关系表应该是什么样的-需要确认我的技术

我的Objective-C单例应该是什么样?

暂停单声道-单声道类型应该是什么样?

“共享”功能的请求规范应该是什么样的?

我的json应该是什么样的?使用Web套接字发送消息

使用Enzyme和useContext钩子的简单集成测试应该是什么样的?

什么样的标志/权限实现应该是?

SQL查询应该是什么?

dummy()函数-应该是什么?

在Python 3.5中,生成器函数的返回类型批注应该是什么样的?