【问题标题】:Parse/Read Bitmap file in C在 C 中解析/读取位图文件
【发布时间】:2013-07-31 10:07:13
【问题描述】:

我正在尝试编写一个程序来从位图文件(.bmp,Windows 文件格式,8 位)中读取数据。现在我一直在阅读图像数据之前的标题。

我使用我找到的 here 的 bmp 规范来制作这些结构来保存 bmp 的文件头、信息头和图像数据:

typedef struct {                                                                                                                                                                                                                             
    unsigned char fileMarker1;                                                                                                                                                                                              
    unsigned char fileMarker2;                                                                                                                                                                                               
    unsigned int   bfSize;                                                                                                                                                                                                                   
    uint16_t unused1;                                                                                                                                                                                                                        
    uint16_t unused2;                                                                                                                                                                                                                        
    unsigned int   imageDataOffset;                                                                                                                                                            
} FILEHEADER;                                                                                                                                                                                                                                

typedef struct {                                                                                                                                                                                                                             
    unsigned int   biSize;                                                                                                                                                                                                                   
    int            width;                                                                                                                                                                
    int            height;                                                                                                                                                                     
    uint16_t planes;                                                                                                                                                                                                                         
    uint16_t bitPix;                                                                                                                                                                                                                         
    unsigned int   biCompression;                                                                                                                                                                                                            
    unsigned int   biSizeImage;                                                                                                                                                                                                              
    int            biXPelsPerMeter;                                                                                                                                                                                                          
    int            biYPelsPerMeter;                                                                                                                                                                                                          
    unsigned int   biClrUsed;                                                                                                                                                                                                                
    unsigned int   biClrImportant;                                                                                                                                                                                                           
} INFOHEADER;                                                                                                                                                                                                                                

typedef struct {                                                                                                                                                                                                                             
    unsigned char  b;                                                                                                                                                                                                                        
    unsigned char  g;                                                                                                                                                                                                                        
    unsigned char  r;                                                                                                                                                                                                                        
} IMAGE;  

我真的看不出这些有什么问题(除非我的规范来源是错误的,但我在别处看过,在我看来没问题)。

我正在使用以下代码来测试它是否被正确解析:

int main(void) {                                                                                                                                                                                                                             
    FILEHEADER fh;                                                                                                                                                                                                                           
    INFOHEADER ih;                                                                                                                                                                                                                           
    FILE *img = fopen("img.bmp", "rb");
    fread(&fh, sizeof(unsigned char), sizeof(FILEHEADER), img);
    fread(&ih, sizeof(unsigned char), sizeof(INFOHEADER), img);
    printf("fM1 = %c, fM2 = %c, bfS = %u, un1 = %hu, un2 = %hu, iDO = %u\n", fh.fileMarker1, fh.fileMarker2, fh.bfSize, fh.unused1, fh.unused2, fh.imageDataOffset);                                                                         
    printf("w = %d, h = %d\n", ih.width, ih.height);
    return 0;
}

不幸的是,当我运行它时,我得到了错误的结果:

User$ ./images 
fM1 = B, fM2 = M, bfS = 0, un1 = 0, un2 = 118, iDO = 2621440
w = 3276800, h = 65536

根据该链接,未使用的 1 和 2 应始终为 0。此外,宽度和高度完全错误(这是 16x16 图像)。

似乎结构存在某种对齐问题。有人对这个有经验么? (我不想使用任何图像/位图库,我想自己做这一切)。

感谢您的帮助!

【问题讨论】:

  • 如果您直接读取这些结构,请检查结构上的填充以确保您将文件中的数据与结构的布局对齐。 See here
  • 呃,这太愚蠢了。谢谢!

标签: c alignment fread bmp


【解决方案1】:

是的,我忘了打包结构。这可以解决问题。哎呀:

typedef struct __attribute__((__packed__)) {                                                                                                                                                                                                                             
    unsigned char fileMarker1;                                                                                                                                                                                              
    unsigned char fileMarker2;                                                                                                                                                                                               
    unsigned int   bfSize;                                                                                                                                                                                                                   
    uint16_t unused1;                                                                                                                                                                                                                        
    uint16_t unused2;                                                                                                                                                                                                                        
    unsigned int   imageDataOffset;                                                                                                                                                            
} FILEHEADER;                                                                                                                                                                                                                                

typedef struct __attribute__((__packed__)) {                                                                                                                                                                                                                             
    unsigned int   biSize;                                                                                                                                                                                                                   
    int            width;                                                                                                                                                                
    int            height;                                                                                                                                                                     
    uint16_t planes;                                                                                                                                                                                                                         
    uint16_t bitPix;                                                                                                                                                                                                                         
    unsigned int   biCompression;                                                                                                                                                                                                            
    unsigned int   biSizeImage;                                                                                                                                                                                                              
    int            biXPelsPerMeter;                                                                                                                                                                                                          
    int            biYPelsPerMeter;                                                                                                                                                                                                          
    unsigned int   biClrUsed;                                                                                                                                                                                                                
    unsigned int   biClrImportant;                                                                                                                                                                                                           
} INFOHEADER;                                                                                                                                                                                                                                

typedef struct __attribute__((__packed__)) {                                                                                                                                                                                                                             
    unsigned char  b;                                                                                                                                                                                                                        
    unsigned char  g;                                                                                                                                                                                                                        
    unsigned char  r;                                                                                                                                                                                                                        
} IMAGE;

【讨论】:

    猜你喜欢
    • 2020-08-01
    • 1970-01-01
    • 2012-10-29
    • 1970-01-01
    • 2021-03-21
    • 2010-10-13
    相关资源
    最近更新 更多