简体   繁体   English

如何读取大位图图像的大小

[英]How to read the size of a big bitmap image

I'm having problems reading big bitmap images. 我在读取大位图图像时遇到问题。 Note that this is a 24bit BMP file. 请注意,这是一个24位的BMP文件。 So I have an image with a size of 800x600. 因此,我的图像尺寸为800x600。 In the file, where it tells the width and height I get this. 在文件中,它告诉宽度和高度,我得到了这个。

Width (4 bytes): 宽度(4个字节):

20 03 00 00

Height (4 bytes): 高度(4个字节):

58 02 00 00

I have exported both with Paint.NET and MS Paint programs. 我已经用Paint.NET和MS Paint程序导出了。 Both had the same output. 两者具有相同的输出。 It seems that when images get big, the calculations get wrong. 看起来当图像变大时,计算会出错。 With small images (100x100 and so) the results are what I want. 对于小图像(100x100等),结果是我想要的。 I have tested changing the size manually (width=800;) and it works perfectly for what I need. 我已经测试过手动更改大小(宽度= 800;),它完全可以满足我的需要。 What I do is sum all the bytes and put together on an integer. 我要做的是将所有字节加起来,然后放到一个整数上。

Example: (I store the file on a vector called store): 示例:(我将文件存储在名为store的向量上):

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

I then made the program create a file to tell me how width was stored. 然后,我使程序创建了一个文件来告诉我宽度的存储方式。

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

This is the output I get: 这是我得到的输出:

35
35
23

So, what am I doing wrong? 那么,我在做什么错呢?

NOTE : -The width info is at location 0x12 and height is at 0x16. 注意 :-宽度信息位于位置0x12,高度位于0x16。 -The file is 800x600. -文件为800x600。 -I don't know how the height is, but I know it is wrong as well. -我不知道身高如何,但我也知道那是错误的。

There are a couple things wrong with how you're computing the width. 计算宽度的方式有几处错误。

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

What you are doing here with your example of width is this: 您在这里用宽度示例做的是这样的:

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

Which is this in decimal: 这是十进制的:

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

This doesn't get you the real value of 20 03 00 00 because in this case 03 isn't supposed to represent 0x03, it's supposed to represent 0x0300 (768 in decimal). 这并不能为您提供20 03 00 00的实际值,因为在这种情况下,03不应表示0x03,而应表示0x0300(十进制768)。

Why does this work with small numbers? 为什么这对少量数字有效? The answer would be that you would be adding together one number with 3 pairs of zeros in the digits that would normally need to be multiplied to get their real values. 答案是,您将一个数字与数字中的3对零相加在一起,通常需要将它们相乘以获得它们的实际值。 (Example: width of 32 would be 20 00 00 00, which would add together 0x20 + 0x00 + 0x00 + 0x00 to get 0x20, which is still 32 in decimal) (示例:32的宽度将为20 00 00 00,将0x20 + 0x00 + 0x00 + 0x00加起来得到0x20,其仍为十进制32)

If you haven't noticed yet, the bitmap holds the values in little-endian order. 如果您尚未注意到,则位图将以Little-Endian顺序保存值。 In other words, the value of width together would not be 0x20030000 (537067520 in decimal), it would be 0x00000320 (800 in decimal, the width of your bitmap). 换句话说,width的值不为0x20030000(十进制为537067520),而是0x00000320(十进制为800,即位图的宽度)。

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

may work in this case, but not only might this break the aliasing rules, this will only work on your implementation if uints are little-endian as well. 在这种情况下可能会起作用,但不仅可能会破坏别名规则,而且仅在uint为little-endian时,这才对您的实现有效。 If they are big-endian, your width would be calculated as 0x20030000 (537067520) instead of 0x00000320 (800). 如果它们是big-endian,则您的宽度将计算为0x20030000(537067520),而不是0x00000320(800)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM