我正在尝试用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'
?对不起我的英语不好。
答案 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];
或类似的,以确保字节以正确的顺序排列,而不管本机字节序。