2016-06-12 91 views
0

ビットマップ(.bmp)イメージヘッダーをcのstructに読み込もうとしています。freadが構造体にデータを正しく読み込みません。

typedef unsigned short WORD; 
typedef unsigned long DWORD; 

typedef struct _BITMAPFILEHEADER { 
    WORD Type; 
    DWORD Size; 
    WORD Reserved1; 
    WORD Reserved2; 
    DWORD OffBits; 
} BITMAPFILEHEADER; 

ビットマップファイルを読み込むための私のコード

FILE *fp; 
BITMAPFILEHEADER header; 

fp = fopen(file,"rb"); 
if (fp == NULL) { 
    printf("cannot open file!\n"); 
    return 1; 
} 

fread(&header, sizeof(BITMAPFILEHEADER), 1, fp); 

printf("Type: %02x\n", header.Type); 
printf("Size: %04x\n", header.Size); 
printf("Reserved: %02x\n", header.Reserved1); 
printf("Reserved: %02x\n", header.Reserved2); 
printf("Offset: %04x\n", header.OffBits); 

は何をすべて等しくなければならない:
タイプ:0x424d
サイズ:0x00060436
Reserved1:0x00
Reserved2を:0x00
オフセット:
タイプ:0x424d
サイズ:0x0006
予約:0x002
は予約:実際には(printfの出力を)happningは何0x00000436

0x436
オフセット:0x280000

を(私のOSは32ビットのubuntuであれば役に立ちます)

+1

固定幅の整数が必要な場合は、標準で提供されているものを使用してください。自家製のタイプは使用しないでください。また、abolutの 'struct'レイアウトと、オクテットストリームを正しく直列化/マーシャルする方法を読んでください。 – Olaf

+5

http://c-faq.com/struct/io.html、http://c-faq.com/struct/padding.html – melpomene

+2

データはどのようにファイルに書き込まれましたか?あなたは、データを読むときに書かれた方法を模倣する必要があります。構造体にパディングがある場合(ほとんどの場合はそうですが)、データが断片的に書かれている場合(パディングがない場合とほぼ同じです)、データを読み込むことはできません。別の 'fread()'操作で各要素を順番に読み込む必要があります。そして、 'fread()'が返ってきたと思うものを使う前に、各fread()が成功していることを確認する必要があります。 –

答えて

0

この種のファイルを読むときは、最初にそれらをバイトストリーム(unsigned char)として読み取ってから、必要に応じて適切なデータ型に従ってファイルの内容の一部を解釈することをお勧めします。それから私は、14バイトのブロックとしてヘッダの内容を読んでいましたし、最後に、私は上に行くだろう

typedef struct _BITMAPFILEHEADER { 
    unsigned char Type[ 2 ]; 
    unsigned int Size;   // Size of the BMP file in bytes 
    unsigned char Reserved1[ 2 ]; 
    unsigned char Reserved2[ 2 ]; 
    unsigned int OffBits;  // Starting address of the pixel array 
} BITMAPFILEHEADER; 

:あなたのケースでは

は、例えば、私はこのようなBITMAPFILEHEADER構造体を定義しますBITMAPFILEHEADER構造体を正しく記入してください。

BMPファイルのヘッダーを読み取って画面に表示する簡単なプログラムがあります。

int main 
    (
    ) 
    { 
    // Defines a few variables 
    FILE*   fp = 0; 
    unsigned char h[ 14 ]; 

    // Opens the BMP file 
    fp = fopen("img.bmp", "rb"); 

    if (fp == NULL) 
     { 
     printf("Cannot open file\n"); 
     return -1; 
     } 

    // Reads the BMP header (14 bytes) 
    fread(h, 14, 1, fp); 

    // Prints the header contents 
    printf("Type:  %02x%02x\n", h[ 0 ], h[ 1 ]); 
    printf("Size:  %02x%02x%02x%02x\n", h[ 2 ], h[ 3 ], h[ 4 ], h[ 5 ]); 
    printf("Reserved: %02x%02x\n", h[ 6 ], h[ 7 ]); 
    printf("Reserved: %02x%02x\n", h[ 8 ], h[ 9 ]); 
    printf("Offset: %02x%02x%02x%02x\n", h[ 10 ], h[ 11 ], h[ 12 ], h[ 13 ]); 

    return 0; 
    } 

注1 - パディング: BMPファイル形式の仕様からprintf("%d", sizeof(BITMAPFILEHEADER))はへのコメントを参照してください(原因パディングに異なる(大きい!)番号が表示されますが、私たちは、ヘッダは14バイトの長さであることを知っていますあなたの質問)。

注2 - エンディアン: 2バイトまたは4バイトをそれぞれ短くまたは長いバイトに書き込む場合は、エンディアンを考慮する必要があります。これは、値がファイルにどのように書き込まれているかを知る必要があることを意味します(Bitmapヘッダーはリトルエンディアン表記で表現されます)。

+1

'unsigned char [2] Type;'は構文エラーです。 –

+1

あなたは 'unsigned char Type [2];'を意味すると仮定すると、構造体定義は 'Size'の前にまだパディングされていないので本当に助けになりません。サンプルプログラムと同様に、予想されるサイズの符号なしcharバッファを読み取る方が良いでしょう。しかし、あなたのプログラムにはエンディアンの問題があります。 –

+1

BMPファイルは常にlittle-endian afaikにあります。 – rici

関連する問題