1

私はしばらくの間画像処理に取り組んできましたが、奇妙なことに気づきました。私はBMPファイルを読んでおり、ReadFileなどの単純なメソッドを使用し、MicrosoftのBMP構造を使用しています。コードは次のとおりです。

 ReadFile(_bmpFile,&bmpfh,sizeof(bfh),&data,NULL);
 ReadFile(_bmpFile, &bmpih, sizeof(bih), &data, NULL);
 imagesize = bih.biWidth*bih.biHeight;
 image = new RGBQUAD[imagesize];
 ReadFile(_bmpFile,image, imagesize*sizeof(RGBQUAD),&written,NULL);

このようにしてファイルを読み取り、単純なforループを使用してグレースケールに変換します。

  for (int i = 0; i < imagesize; i++)
  {
       RED = image[i].rgbRed;
       GREEN = image[i].rgbGreen;
       BLUE = image[i].rgbBlue;
       avg = (RED + GREEN + BLUE ) / 3;
       image[i].rgbRed = avg;
       image[i].rgbGreen = avg;
       image[i].rgbBlue = avg;
  }

このコードを使用してファイルを作成すると、次のようになります。

#pragma pack(push, 1)
WriteFile(_bmpFile, &bmpfh, sizeof(bfh), &data, NULL);
WriteFile(_bmpFile, &bmpih, sizeof(bih), &data, NULL);
WriteFile(_bmpFile, image, imagesize*sizeof(RGBQUAD), &written, NULL);
#pragma pack(pop)

ファイルはさらに大きくなっています(30MB-> 40MB)。

これが発生する理由は、RGBTRIPLEの代わりにRGBQUADを使用しているためですが、RGBTRIPLEを使用している場合、小さな画像をグレースケールに変換する際に問題が発生します-作成後に画像を開くことができません(正しい構造ではないと言います) 。

また、ファイルサイズに1バイトがありません(1174kb以降1173kb以降)

誰かがこれを以前に見たことがありますか(小さな写真でのみ発生します)?

4

3 に答える 3

3

BMPファイルでは、次のスキャンラインが32ビット境界で開始するように、すべてのスキャンラインをパディングする必要があります。ピクセルあたり32ビットを実行する場合、これは自動的に行われますが、ピクセルあたり24ビットを使用する場合は、明示的に実行するためのコードを追加する必要があります。

于 2011-03-26T18:02:39.057 に答える
2

あなたはストライド(ジェリーのコメント)とビットマップのピクセルフォーマットを無視しています。ファイルサイズの増加から判断すると24bppで、32bppのように書いています。あなたのグレースケール変換は間違っています、人間の目は赤、緑、青に等しく敏感ではありません。

GDI +の使用を検討して<gdiplus.h>ください。ビットマップクラスを使用するには、コードに#includeします。そのLockBits()メソッドを使用すると、ビットマップビットにアクセスできます。ColorMatrixEffectクラスを使用すると、1回の操作で色変換を適用できます。グレースケール画像を取得するために必要なカラーマトリックスについては、この回答を確認してください。MSDNドキュメントはここから始まります

于 2011-03-26T18:27:47.270 に答える
0

BMPの各水平行は、4バイトの倍数である必要があります。

ピクセルデータが4バイトの倍数を占めない場合、0x00バイトが行の最後に追加されます。24 bppの画像の場合、1行あたりのバイト数は(imageWidth * 3 + 3)&〜3です。パディングバイト数は((imageWidth * 3 + 3)&〜3)-(imageWidth * 3)です。

これはimmibisによって答えられました。

配列のサイズは((imageWidth * 3 + 3)&〜3)*imageHeightであることを追加したいと思います。これがお役に立てば幸いです

于 2015-01-17T09:03:15.327 に答える