0

BMP ファイルは (ピクセル単位で) 下から上に書き込まれるため、BMP ファイルを逆方向​​に読み取る (そして 54 バイトのヘッダーを取り除く) 必要があります。これまでの私のコード:

public string createNoHeaderBMP(string curBMP)  //copies everything but the header    from the curBMP to the tempBMP
    {
        string tempBMP = "C:\\TEMP.bmp";

        Stream inStream = File.OpenRead(curBMP);
        BinaryReader br = new BinaryReader(inStream);

        byte[] fullBMP = new byte[(width * height * 3) + 138];
        byte[] buffer = new Byte[1];
        long bytesRead;
        long totalBytes = 0;

        while ((bytesRead = br.Read(buffer, 0, 1)) > 0)
        {
            fullBMP[fullBMP.Length - 1 - totalBytes] = buffer[0];
            totalBytes++;
        }

        FileStream fs = new FileStream(tempBMP, FileMode.Create, FileAccess.Write);
        fs.Write(fullBMP, 54, fullBMP.Length - 54);
        fs.Close();
        fs.Dispose();

        return tempBMP;
    }

何らかの理由でジョブを完全に実行できず、右側の一部が左側に配置された画像になります。ファイルを完全に逆にしないのはなぜですか? また、これらの BMP ファイルは非常に大きい (600 MB) ため、「メモリ不足」例外が発生するため、単純なメモリ ストリームを使用してシーク アンド スワップ操作を行うことはできません。

4

2 に答える 2

2

私は BMP の仕様を確認しておらず、知識もありません。私はあなたの言うことが真実であると仮定します。

ビットマップを表示するほとんどのプログラムは、ヘッダーを読み取って画像の大きさを確認し、データを上から下に読み取り、ビットマップを下から上に描画します。また、ほとんどのファイルをシークすることもできます。inStreamそのため、ファイル全体をメモリに保持する必要なく、それを使用してシークできます。

次に、600 MiB のバイト配列 (つまり、メモリ内に 600 MiB の構造体) を割り当てることができれば、MemoryStream最大 600 MiB のメモリ空間を占める a を確実に割り当てることができます。または、 を取得する場合は、 を使用するか を使用するかOutOfMemoryExceptionに関係なく取得します。後者の方が作業が簡単です。byte[]MemoryStream

RGB 形式 (または現在の形式) から BGR に各ピクセルの色を逆にしたことを認識しない限り、すべてを逆にするという考えは失敗します。また、BMP スキャン ラインの方向はわかりませんが、左から右に実行されている場合は、反転したビットマップの画像が水平方向に反転します。

右側の画像の一部を左側に表示する理由は、ビットマップのバイトを逆にして正しく出力されると期待できないためです。また、スキャン ラインを描画するときに、スキャン ラインの長さが間違っている可能性があります。

また、ヘッダーが 54 バイトであると言いますが、138 バイトを の配列サイズに追加しますfullBMP。定数を確認してください。変更されないことが保証されているかどうかを確認してから、const. 彼らは変わることができますか?次に、ビットマップからそれらを読み取ります。

于 2013-04-01T13:42:49.230 に答える