2013-07-31 56 views
1

我试图让一个程序从位图文件(.bmp,Windows文件格式,8位)读取数据。现在,我一直在阅读图像数据之前的标题。解析/读取位图文件C

我用BMP的规格为BMP,我发现here使这些结构来保存文件头,信息头和图像数据:

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 

根据该链接,unused1和2应该总是0.另外,宽度和高度是完全错误的(这是一个16x16的图像)。

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

感谢您的帮助!

+3

如果您直接阅读这些结构,请检查结构上的填充以确保将文件中的数据与结构的布局对齐。 [见这里](http://stackoverflow.com/questions/17255104/how-can-i-read-a-bmp-file-and-access-its-header-info-via-a-struct-pointer-withou ?rq = 1) – Joe

+0

呃那是愚蠢的。谢谢! –

回答

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;