2013-07-31 81 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;