You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言非Windows环境读取BMP文件头出现biSize数值过大问题

问题原因与解决方案

你验证得到bfType字段正常的结果刚好可以佐证核心问题为结构体对齐填充,该字段是结构体首个成员,不受填充影响所以读取正确,后续成员全部因为字节错位读取失败。

1. 修复结构体字节对齐问题

C编译器默认开启内存对齐优化,会在结构体成员之间插入填充字节,你定义的BITMAPFILEHEADER实际大小为16字节,而非预期的14字节,fread多读了2字节,导致后续INFOHEADER的读取全部错位。
不同编译器的关闭对齐写法:

GCC/Clang环境

给结构体添加packed属性:

typedef struct __attribute__((packed)) tagBITMAPFILEHEADER {
  WORD  bfType;
  DWORD bfSize;
  WORD  bfReserved1;
  WORD  bfReserved2;
  DWORD bfOffBits;
} BITMAPFILEHEADER;

typedef struct __attribute__((packed)) tagBITMAPINFOHEADER {
    DWORD biSize;
    LONG  biWidth;
    LONG  biHeight;
    WORD  biPlanes;
    WORD  biBitCount;
    DWORD biCompression;
    DWORD biSizeImage;
    LONG  biXPelsPerMeter;
    LONG  biYPelsPerMeter;
    DWORD biClrUsed;
    DWORD biClrImportant;
} BITMAPINFOHEADER;

MSVC环境

使用预编译指令指定对齐粒度:

#pragma pack(1) // 按1字节对齐,取消填充
typedef struct tagBITMAPFILEHEADER {
  WORD  bfType;
  DWORD bfSize;
  WORD  bfReserved1;
  WORD  bfReserved2;
  DWORD bfOffBits;
} BITMAPFILEHEADER;

typedef struct tagBITMAPINFOHEADER {
    DWORD biSize;
    LONG  biWidth;
    LONG  biHeight;
    WORD  biPlanes;
    WORD  biBitCount;
    DWORD biCompression;
    DWORD biSizeImage;
    LONG  biXPelsPerMeter;
    LONG  biYPelsPerMeter;
    DWORD biClrUsed;
    DWORD biClrImportant;
} BITMAPINFOHEADER;
#pragma pack() // 恢复默认对齐

2. 修复基础数据类型定义

非Windows系统下unsigned long长度随系统位数变化,64位系统下为8字节,和Windows下固定4字节的DWORD/LONG定义不符,直接使用C标准库的固定长度整数类型即可:

// 头文件添加这两个包含
#include <stdint.h>
#include <inttypes.h>

// 替换原有类型定义
typedef uint32_t DWORD;
typedef int32_t  LONG;
typedef uint16_t WORD;
typedef uint8_t  BYTE;

3. 修复输出格式化符

使用匹配固定长度类型的格式化符,避免输出错误:

// 替换原有printf语句
printf("size: %" PRIu32 "\n", dib.biSize);

修复后正常的BITMAPINFOHEADER的biSize字段值应为40,符合标准BMP格式定义。

内容的提问来源于stack exchange,提问作者Navxihziq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 05:45:02