C语言读取BMP文件时为何不能直接转换header[18]为int获取宽度
问题解答
核心原因
BMP文件头中存储的图像宽度是4字节(32位)的有符号整数,数据保存在从偏移18开始的连续4个字节中,并非仅存储在第18个字节这1个字节里。
你尝试的写法int width=(int)(header[18]);存在明显问题:
header数组的每个元素是unsigned char类型,仅占用1个字节,header[18]只能取到偏移18位置的单个字节数据- 强制类型转换只是把这1个字节的数值转成int类型,相当于只拿到了32位宽度数据的最低8位(小端序场景下),只要宽度大于255(单字节可表示的最大正整数),取值就完全错误,比如你用到的lena512.bmp宽度为512,单个字节根本存不下这个数值。
原代码的逻辑说明
int width=*(int*)(&header[18]); 实际分三步执行:
- 用
&header[18]拿到header数组第18个元素的内存地址,此时地址的类型是unsigned char* - 用
(int*)把该地址强制转换为int类型指针,告诉编译器:这个地址开始的连续4个字节需要按照int类型来解析 - 用
*解引用这个int指针,一次性读取地址开始的4个字节,拼接成完整的32位int值,得到正确的图像宽度。
注意:这个写法隐含了字节序匹配的前提:BMP文件规定数值用小端序存储,x86、x86_64等常用平台也默认是小端序,所以代码可以正常运行;如果是在大端序平台执行,还需要额外做字节序转换才能得到正确数值。
内容的提问来源于stack exchange,提问作者Nishani Kasineshan
相关产品推荐
相关产品推荐

