【问题标题】:How to read the size of a big bitmap image如何读取大位图图像的大小
【发布时间】:2014-09-10 21:27:35
【问题描述】:

我在读取大位图图像时遇到问题。请注意,这是一个 24 位 BMP 文件。 所以我有一个尺寸为 800x600 的图像。 在文件中,它告诉我得到这个的宽度和高度。

宽度(4 字节):

20 03 00 00

高度(4 字节):

58 02 00 00

我已使用 Paint.NET 和 MS Paint 程序导出。两者都有相同的输出。 似乎当图像变大时,计算就会出错。 使用小图像(100x100 等),结果就是我想要的。 我已经测试过手动更改大小(宽度= 800;),它非常适合我的需要。 我所做的是将所有字节相加并放在一个整数上。

示例:(我将文件存储在一个名为 store 的向量中):

unsigned int width = store[0x12] + store[0x13] + store[0x14] + store[0x15];

然后我让程序创建一个文件来告诉我宽度是如何存储的。

ofstream s("hht.txt");
        s <<  width;
        s << "\n";
        s << dec << width;
        s << "\n";
        s << hex << width;
        s.close();

这是我得到的输出:

35
35
23

那么,我做错了什么?

注意: - 宽度信息位于 0x12 位置,高度位于 0x16。 - 文件为 800x600。 -我不知道高度是多少,但我也知道它是错误的。

【问题讨论】:

  • 试试store[0x12] + store[0x13] &lt;&lt; 8 + store[0x14] &lt;&lt; 16 + store[0x15] &lt;&lt; 24,看看效果如何。
  • 当你看到像1024这样的数字时,你加1+0+2+4吗?
  • 试试width = *reinterpret_cast&lt;uint32_t&gt;(&amp;store[0x12]) ;)
  • @user3804254:您正在查看 32 位 little-endian 十六进制数字。 0x00000320 等于十进制的 800,0x00000258 是 600。
  • 这里只是一个答案是不够的,我也懒得在这里解释变量的内存布局——你可能会在网上找到一些关于它的东西:P。正如已经指出的那样,请阅读有关可变大小和小端机器的信息。

标签: c++ bitmap binary hex decimal


【解决方案1】:

您计算宽度的方式存在一些问题。

unsigned int width = store[0x12] + store[0x13] + store[0x14] + store[0x15];

您在这里使用宽度示例所做的是:

unsigned int width = 0x20 + 0x03 + 0x00 + 0x00; // width = 0x23

这是十进制:

unsigned int width = 32 + 3 + 0 + 0; // width = 35

这不会得到 20 03 00 00 的实际值,因为在这种情况下,03 不应该代表 0x03,它应该代表 0x0300(十进制的 768)。

为什么这适用于小数字?答案是您将一个数字与数字中的 3 对零相加,这些数字通常需要相乘才能得到它们的实际值。 (例如:32 的宽度是 20 00 00 00,0x20 + 0x00 + 0x00 + 0x00 相加得到 0x20,仍然是十进制的 32)

如果您还没有注意到,位图以 little-endian 顺序保存值。换句话说,宽度的值加起来不会是 0x20030000(十进制的 537067520),而是 0x00000320(十进制的 800,位图的宽度)。

width = *reinterpret_cast<uint32_t>(&store[0x12])

在这种情况下可能会起作用,但这不仅可能会破坏别名规则,而且仅当 uint 也是 little-endian 时才对您的实现起作用。如果它们是大端,则您的宽度将计算为 0x20030000 (537067520) 而不是 0x00000320 (800)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-21
    • 1970-01-01
    • 2020-01-25
    • 2012-06-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多