2016-11-17 19 views
0

にBMP画像のフォーマットエラーを書いてください...私はREADWRITEに、WindowsでLinuxからの同じコード(コピー&ペースト)を使用し、よBMP画像。そして何らかの理由でのLinuxがすべて動作しますWindows 10からいくつかの画像を開くことができません。エラーメッセージが表示されます。C++:私はここで最も奇妙な問題を抱えているWINDOWS

"このファイル形式はサポートされていないようです。"

私は何をすべきですか?私は以下のコードを記入します。

EDIT:

任意のアイデアなぜ、私は、パディングの問題を解決してきたし、今では、画像の書き込みだが、彼らは完全にですか?私もコードを更新しました。

struct BMP { 
    int width; 
    int height; 
    unsigned char header[54]; 
    unsigned char *pixels; 
    int size; 
    int row_padded; 
}; 

void writeBMP(string filename, BMP image) { 
    string fileName = "Output Files\\" + filename; 
    FILE *out = fopen(fileName.c_str(), "wb"); 
    fwrite(image.header, sizeof(unsigned char), 54, out); 

    unsigned char tmp; 
    for (int i = 0; i < image.height; i++) { 
     for (int j = 0; j < image.width * 3; j += 3) { 
      // Convert (B, G, R) to (R, G, B) 
      tmp = image.pixels[j]; 
      image.pixels[j] = image.pixels[j + 2]; 
      image.pixels[j + 2] = tmp; 
     } 
     fwrite(image.pixels, sizeof(unsigned char), image.row_padded, out); 
    } 
    fclose(out); 
} 

BMP readBMP(string filename) { 
    BMP image; 
    string fileName = "Input Files\\" + filename; 
    FILE *f = fopen(fileName.c_str(), "rb"); 

    if (f == NULL) 
     throw "Argument Exception"; 

    fread(image.header, sizeof(unsigned char), 54, f); // read the 54-byte header 

    // extract image height and width from header 
    image.width = *(int *) &image.header[18]; 
    image.height = *(int *) &image.header[22]; 

    image.row_padded = (image.width * 3 + 3) & (~3); 
    image.pixels = new unsigned char[image.row_padded]; 
    unsigned char tmp; 

    for (int i = 0; i < image.height; i++) { 
     fread(image.pixels, sizeof(unsigned char), image.row_padded, f); 
     for (int j = 0; j < image.width * 3; j += 3) { 
      // Convert (B, G, R) to (R, G, B) 
      tmp = image.pixels[j]; 
      image.pixels[j] = image.pixels[j + 2]; 
      image.pixels[j + 2] = tmp; 
     } 
    } 
    fclose(f); 
    return image; 

} 

私の見解では、このコードはクロスプラットフォームでなければなりません...しかし、それはなぜですか? 0x42 0x4D:ヘルプ

+0

Visual Studioに付属のwindiffのようなウィンドウで比較ツールを使用して、2つのファイルを比較することができます。デバッガを使用して同じイメージヘッダーデータが書き込まれていることを確認します。 –

+0

何を比較する?それはまったく同じコードです... – Mircea

+0

私はこのコードを数回チェックしましたが、まったく同じです... – Mircea

答えて

1

チェックheaderは、次の2つのsignatureバイトで開始する必要がありますヘッダー

ため

感謝。もしそれが違うなら、サードパーティのアプリケーションは、.bmpファイルの拡張子にもかかわらず、このファイルにbmp画像が含まれていないと思うでしょう。

ピクセルが格納されるサイズと方法も少しですmore complex than what you expect:ピクセルあたりのビット数は24であり、圧縮は使用されていないと仮定します。これは保証されていません。そうでない場合は、使用可能なデータよりも多くのデータを読み込み、ファイルを書き戻すときに破損する可能性があります。

さらに、ヘッダのサイズは、あなたのコード

あなたがファイルをロード、チェックを改善14.

をオフセットで4バイトの整数をyou can detect using使用しているBMP version、にも依存しますシグネチャ、bmpバージョン、1ピクセルあたりのビット数、圧縮率などがあります。目的をデバッグするために、手動でそれを確認するために、ヘッダーをダンプ考える:

さらに、あなたはバイトの数はそうあなたがじゃないことを確認するために、あなたが読みたかったサイズに対応して読むことを確認しfread()とき
for (int i=0; i<54; i++) 
    cout << hex << image.header[i] << " ";` 
cout <<endl; 

初期化されていないバッファデータを処理します。

編集:

がダンプを確認したので、予想通りの形式があることが表示されます。しかし、あなたは、エラーがここにあることが表示されます計算したパッ​​ド入りのサイズとヘッダでパディングサイズを検証:実際には

image.row_padded = (image.width * 3 + 3) & (~3);  // ok size of a single row rounded up to multiple of 4 
image.pixels = new unsigned char[image.row_padded]; // oops ! A little short ? 

あなたは、行単位で読みますが、あなただけのメモリ内の最後の1をキープ!これは、画像の全画素を読んだ最初のバージョンとは異なります。

同様に、最後の行に高さの時間を繰り返し書きます。

詰め物のサイズを調整してください。

+0

私は私の問題の一部を解決しました、私は私の質問を編集する、あなたはもう一度それを確認することができますか? – Mircea

+0

@Mircea私は答えを編集しました – Christophe

+0

...入力画像は大丈夫です、私はそれを開いて見ることができます。私の問題は単なる出力イメージです。私はすでにヘッダーの倍数の時間をチェックしており、それは完璧です、または私は違いを見ることができませんでした。私は 'for(int i = 0; i <54; i ++)であってもチェックしています.cout << hex << image.header [i] <<" ";;これは同じです。 、この瞬間に私の問題はヘッダーではなく、ピクセル配列です。何らかの理由で私は何とか思っていたピクセルをすべて失ってしまっています...または正しく書き込んでいません。私はそれがこの瞬間に私の問題だと思う。 – Mircea

関連する問題