BMP 标题应该是什么样子?

发布于 2025-01-20 09:38:16 字数 1925 浏览 4 评论 0 原文

我正在尝试编写代码来读取 BMP 文件,因此我正在尝试读取 BMP 标头。我正在使用某个代码库中的测试图像,但看起来该结构与 Wikipedia 上有关 BMP 图像结构的信息不符 维基百科BMP结构 ,特别是部分,where should be offset storage(“位图图像数据所在字节的偏移量,即起始地址(像素数组)可以在维基百科的表格中找到,因为图像的开始看起来如下所示:

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 header docs.fileformat.com BMP 结构 显示相同的偏移量,但实际情况不同由于某种原因在这里。你能带我到这里前进吗?

PS:我会在此处粘贴原始图像,但看起来图像会自动导出为 png 格式。

I am trying to write a code to read a BMP file so I am trying to read BMP header(s). I am using a test image from some code library but it looks, like the structure doesn't correspond with the information about BMP image structure on Wikipedia Wikipedia BMP structure , especially in part, where should be offset stored ("The offset, i.e. starting address, of the byte where the bitmap image data (pixel array) can be found. ") in the table on Wikipedia as the start of the image looks like following:

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.

So there is clear that the image starts on 36h and not 436h as is should look like according to Wikipedia - looks for me like the valid information has 1 Byte, not 4 Bytes. So I tried to find another source of the information about the header and I've found only the same information as is described in the mentioned article.

I thought that I have wrong image stored, so I decided to open it via Gimp and store it as the new-one, but it looks like the header has the same structure, just start of the image is moved.

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....

So not only that Gimp reads the header with no issue, but it even creates header of the same type. But according to the documentation it looks like the binary part should be stored on 436h, respective 47Ah as there should be little endian used. I am clearly missing something there but I can't get the point as the different sources fastgraph.com BMP header docs.fileformat.com BMP structure shows the same offsets but reality differs here for some reason. Can you move me forward here?

PS: I would paste here original image, but it looks like the image is automatically exported to png format.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

苯莒 2025-01-27 09:38:16

tl;dr:在你的图像中有一个颜色表。当有颜色表时,它位于 DIB 标头之后,然后是像素数据。由于颜色表从 0x36 到 0x435,因此像素数据本身确实位于 0x436。

我上次使用它时,维基百科关于 BMP 格式的文章是正确的,比大多数其他来源更全面、更好。

BMP 文件具有文件头和位图信息头(有时称为 DIB 头)。像素数据可能在信息标头之后立即开始,但可能有附加的颜色信息和/或填充。之后是像素数据。

根据您的第一个十六进制转储,文件头显示像素数据从 0x0436 开始是正确的。您没有显示足够的文件来查看像素数据是否实际上从 0x0436 开始,但我们可以检查 DIB 标头以查看它是否一致。

DIB header 比较复杂,因为有很多版本。从偏移量 0x0E 开始,我们可以读取 DIB 标头的大小为 0x28(或十进制 40)。这告诉我们它是一个普通的 BITMAPINFOHEADER

位图大小为 227x149 像素。 (请注意,因为奇数宽度很难得到正确的结果。)

像素格式为每像素 8 位,BI_RGB 是压缩值。因此,标题之后、像素数据之前将会有一个颜色表(调色板)。事实上,标题明确表示将有 256 个颜色表条目。

所以颜色表从0x36开始。颜色表中的每个条目为 4 个字节 (RGBQUAD),因此表长度为 256 种颜色 * 4 字节/颜色 = 1024 字节。因此该表从 0x36 到 0x435。

像素数据可以位于颜色表之后的任何位置,只要它与 4 字节边界对齐即可。由于 0x0436 是 4 的倍数,因此这是第一个可能的可用地址。这也正是文件头表示像素数据的位置。

(当您使用 Gimp 保存图像时,Gimp 选择使用不同版本的位图信息标头(长度为 0x6C 字节)来保存它,并且使用不同的像素格式,因此像素数据以较大的偏移量开始也就不足为奇了。)

tl;dr: In your image there's a color table. When there's a color table, it comes after the DIB header, and the pixel data is after that. Since the color table runs from 0x36 to 0x435, the pixel data itself is indeed at 0x436.

The last time I used it, the Wikipedia article on the BMP format was correct and more thorough and better presented than most other sources.

A BMP file has a file header and then a bitmap info header (sometimes called the DIB header). The pixel data might start immediately after the info header, but there may be additional color information and/or padding. The pixel data is after that.

Based on your first hex dump, you are correct that the file header says the pixel data starts at 0x0436. You don't show enough of the file to see whether the pixel data actually starts at 0x0436, but we can inspect the DIB header to see if it's consistent.

The DIB header is more complex because there are many versions. Starting at offset 0x0E, we can read that size of the DIB header is 0x28 (or 40 decimal). That tells us it's a vanilla BITMAPINFOHEADER.

The bitmap size is 227x149 pixels. (Watch out, because odd widths can be tricky to get just right.)

The pixel format is 8 bits per pixel and BI_RGB is the compression value. So there will be a color table (palette) after the headers and before the pixel data. In fact, the header explicitly says there will be 256 color table entries.

So the color table starts at 0x36. Each entry in the color table is four bytes (RGBQUAD), so the table length is 256 colors * 4 bytes/color = 1024 bytes. Thus the table runs from 0x36 to 0x435.

The pixel data can come anywhere after the color table as long as it's aligned to a 4-byte boundary. Since 0x0436 is a multiple of 4, that's the first possible address available. It's also exactly where the file header said the pixel data would be.

(When you saved the image with Gimp, Gimp chose to save it using a different version of the bitmap info header that's 0x6C bytes long and it uses a different pixel format, so it's not surprising that the pixel data starts at a larger offset.)

故人爱我别走 2025-01-27 09:38:16

感谢所有答复!

在所有响应之后,我确实确实错误了,因为我认为位图调色板的开始是图像的开始,因为启动时的颜色看起来像图像的第一个像素中的颜色。所有答复对我来说都是有用的,因为他们帮助我更好地理解了这个话题。在Martin Rosenau Read发表评论后,这帮助我理解了错误,也很有帮助文章。

Thanks for all replies!

After all responses it looks that I did mistake because I have thought that start of bitmap palette is start of the image, because the color on the start looked like the color in the first pixel of the image. All replies were useful for me as they helped me understand the topic better. After there was comment from Martin Rosenau read, which helped me to understand my mistake, was also helpful http://libertybasicuniversity.com/lbnews/nl100/format.htm article.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文