用C ++读取bmp文件的宽度和高度

时间:2017-02-11 20:21:13

标签: c++ image bitmap bmp

我正在尝试用C ++读取bmp文件的宽度和高度。宽度和高度是我的bmp文件的512。 18. byte是bmp文件的宽度值。

我的代码如下所示:

int main() {

char header[54];    
ifstream bmp;
bmp.open("image.bmp", ios::in | ios::binary);   

if (!bmp) {
    cout << "Error" << endl;
    system("PAUSE");
    exit(1);
}

bmp.read(header, 54);

char a = header[18];

int b = *(int *)&header[18];

system("PAUSE");
}

b 512时,a如何成为'\0'?对不起我的英语不好。

3 个答案:

答案 0 :(得分:0)

因为char是一个字节而int是(可能)4个字节。 512作为四字节int看起来像0x00 0x00 0x02 0x00。请注意,这四个字节中只有一个是非零的。

char a = header[18];只读取位置18处的单字节,而int b = *(int *)&header[18];将位置18到21解释为单个int值。

答案 1 :(得分:0)

根据BMP file format,宽度是一个有符号整数,包括4个字节,而不是一个字节。 因此,如果宽度为\begin{frame} \frametitle{Frame SVG example} \begin{figure} \includegraphics[\textwidth]{graphic.svg} \end{figure} \end{frame} ,则 - 当表示为4字节整数时,字节为512并分别从位置18到21存储。因此,第18位是0x00 - 0x00 - 0x02 - 0x00(您的值为0x00),而a在被解释为位置18到21的4字节有符号整数时为width

答案 2 :(得分:0)

我不确定的重要说明可以在评论中进行扩展。

int b = *(int *)&header[18];

header[18]视为int。它不是int。欢迎来到Strict Aliasing。你已经转换了不同的类型你在这里做的是走进未定义的行为。它是USUALLY&#34;工作的那种未定义行为之一&#34;,但考虑到这一点:

header[18]不是32位或64位字节对齐的。读取32位或64位整数时,程序将受到性能损失,因为处理器会玩游戏来读取未对齐的数据,或者因为处理器抬起数字中指并彻底崩溃而死亡。

几乎正确的方法是

int width;
memcpy(&width, &header[18], sizeof(width));

但是这忽略了这样一个事实:标题和程序可能在int的大小和字节顺序上存在分歧。

查看BMP规范,图像宽度是一个小的无符号16位整数。将其读入典型的32位int将导致彻底的垃圾。至少使用uint16_t来祈祷一个小端处理器(在PC硬件上的合理假设)。

uint16_t width;
memcpy(&width, &header[18], sizeof(width));

更好的

uint16_t width = (uint8_t)header[19];
width <<= 8;
width += (uint8_t)header[18]; 

或类似的,以确保字节以正确的顺序排列,而不管本机字节序。