![](/img/trans.png)
[英]I try to write a bmp file in c++, but the bmp file's width and height seems to affect the result,sometimes I got a bad bmp file
[英]Read width and height of bmp file in C++
我正在尝试在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");
}
当a
为'\\0'
时b
如何变为512
? 对不起,我的英语不好。
因为char
是1个字节,而int
是(可能)是4个字节。 512作为一个四字节的int
看起来像0x00 0x00 0x02 0x00
。 请注意,这四个字节中只有一个是非零的。
char a = header[18];
只是读取位置18处的单个字节,而int b = *(int *)&header[18];
将位置18到21解释为单个int
值。
根据BMP文件格式 ,宽度是一个有符号整数,包括4个字节,而不是一个字节。 因此,如果宽度为512
,则-当表示为4字节整数时,字节分别为0x00 - 0x00 - 0x02 - 0x00
并分别从位置18到21存储。 所以18位是0x00
(您的值a
),而width
在从位置18解释为一个4字节的符号整数〜21是512
。
重要说明,我不确定是否可以在评论中进行扩展。
int b = *(int *)&header[18];
将header[18]
视为int
对待。 它不是int
。 欢迎来到严格的别名。 您已经转换了不同的类型,这里要做的就是进入未定义的行为。 这是通常“起作用”的一种不确定行为,但是请考虑以下因素:
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];
或类似的格式,以确保字节以正确的顺序排列,而不管本机字节序如何。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.