读取 BMP 标头,打包。读取不正确的值

Posted

技术标签:

【中文标题】读取 BMP 标头,打包。读取不正确的值【英文标题】:Reading BMP headers, packed. Reading incorrect values 【发布时间】:2011-10-12 10:29:25 【问题描述】:

我最近编写了一个程序来读取 BMP 文件的文件头和信息头。我如图所示包装它们,对它们进行处理,然后打印宽度和高度。不幸的是,宽度和高度不正确。我不确定为什么。也许有点/小端问题?如果是这样,我不知道如何解决它。我正在 GCC 上编译和运行它。

#pragma pack(1)

typedef struct

    unsigned char fileMarker1;       /* 'B' */                       
    unsigned char fileMarker2;       /* 'M' */ 
    unsigned int   bfSize;             
    unsigned short unused1;           
    unsigned short unused2;           
    unsigned int   imageDataOffset;  /* Offset to the start of image data */
 FILEHEADER;

 typedef struct                       
  
    unsigned int   biSize;            
    signed int     width;            /* Width of the image */ 
    signed int     height;           /* Height of the image */ 
    unsigned short planes;             
    unsigned short bitPix;             
    unsigned int   biCompression;      
    unsigned int   biSizeImage;        
    int            biXPelsPerMeter;    
    int            biYPelsPerMeter;    
    unsigned int   biClrUsed;          
    unsigned int   biClrImportant;     
 INFOHEADER;

 #pragma pack()

.....

 fread( &header, sizeof(FILEHEADER), 1, image );

.....

 fread( &iheader, sizeof(INFOHEADER), 1, image );

.....

 printf("Width: %i\n", iheader.width);
 printf("Height: %i\n", iheader.height);

【问题讨论】:

图片的实际尺寸是多少,你得到什么值。用十六进制查看它们是否是字节序问题 你的系统是大端吗?你的系统是什么? 您是否在读取图像数据之前移动到图像数据的开头?数据的偏移量在 FILEHEADER 中指定。 fileMarker1 和 fileMarker2 的值对吗? 根据en.wikipedia.org/wiki/BMP_file_format#Bitmap_file_header"所有的整数值都以little-endian格式存储" 我的定位是正确的,我花了很多时间检查这个,或者重新定位,比如 fseek。文件标记是正确的。我想我必须检查一下字节序。 【参考方案1】:

Windows 位图文件确实以小端方式存储。因此,假设您的系统是 big-endian,您需要在加载后反转每个 2 或 4 字节 int 值的字节序。这个IBM article 描述了各种方法。

【讨论】:

以上是关于读取 BMP 标头,打包。读取不正确的值的主要内容,如果未能解决你的问题,请参考以下文章

C 中的 .BMP 文件 - DIB 标头返回图像大小 0,即使 BMP 标头返回文件大小

在 C++ 中读取 .bmp 文件

在 C 中读取 bmp 标头

通过 AJAX 读取静态地图时的不安全标头警告

从 bmp 文件中读取 RGB 像素

如何批量读取bmp图片的原始高和宽