質問

次のようなファイルから DIBSection をロードしています。

HBITMAP bmpIn = (HBITMAP) LoadImage(NULL, _T("c:\\Temp\\Temp.bmp"), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);

経験的に、ロードされたビットマップと過去に使用したビットマップの間に次の違いがあることを発見しましたが、違いがあるはずであることを記載したドキュメントは見つかりません。

  • 行はメモリ内でボトムアップではなくトップダウンに順序付けされます。.bmp ファイル自体がボトムアップで順序付けされていることを確認しました。
  • 行パディングは 4 バイトではなく 2 バイトの倍数になります。

を使用した場合の文書化された違いも発見しました CreateDIBSection DIBSection を最初から作成します。

  • によって返される DIBSECTION.dsHandle および BITMAP.bmBits の値 GetObject NULLになります。

最初の 2 つの違いに関するドキュメントはどこにありますか?何か足りないものはありますか?これは Windows 7 の場合ですが、Windows の他のバージョンでも異なるとは想像できません。

編集: いくつかの追加の詳細。これは 16 進ダンプです temp.bmp;これは 7x7 の画像で、右側に白いストライプがあり、左側に沿って青い値が増加しています (0x10、0x20 など)。一番下の行 (00,00,70) が最初で、3 バイトのパディングがあることがわかります。

00: 42 4d de 00 00 00 00 00 00 00 36 00 00 00 28 00
10: 00 00 07 00 00 00 07 00 00 00 01 00 18 00 00 00
20: 00 00 a8 00 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 00 00 70 00 00 00 00 00 00 00 00 00
40: 00 00 00 00 00 00 00 00 ff ff ff 00 00 00 60 00
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: ff ff ff 00 00 00 50 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 ff ff ff 00 00 00 40 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: ff ff ff 00 00 00 30 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 ff ff ff 00 00 00 20 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: ff ff ff 00 00 00 10 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 ff ff ff 00 00 00

.bmp ファイルを読み取り、内容を書き出すサンプル プログラムを次に示します。簡潔にするためにエラーチェックを削除しました。

int _tmain(int argc, _TCHAR* argv[])
{
   HBITMAP bmpIn = (HBITMAP) LoadImage(NULL, argv[1], IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
   FILE * out = _tfopen(argv[2], _T("wb"));
   DIBSECTION obj = {0};
   GetObject(bmpIn, sizeof(obj), &obj);
   cout << "dsBm.bmHeight = " << obj.dsBm.bmHeight << endl;
   cout << "dsBmih.biHeight = " << obj.dsBmih.biHeight << endl;
   cout << "sizeof(DIBSECTION) = " << sizeof(DIBSECTION) << endl;
   fwrite(&obj, sizeof(DIBSECTION), 1, out);
   int stride = (((obj.dsBmih.biWidth * obj.dsBmih.biBitCount) + 15) / 16) * 2;
   int bytecount = abs(obj.dsBmih.biHeight) * stride;
   vector<BYTE> bits(bytecount);
   GetBitmapBits(bmpIn, bytecount, &bits[0]);
   fwrite(&bits[0], 1, bytecount, out);
   fclose(out);
   return 0;
}

上記のプログラムの出力と、生成されたファイルの 16 進ダンプは次のとおりです。

dsBm.bmHeight = 7
dsBmih.biHeight = 7
sizeof(DIBSECTION) = 84
00: 00 00 00 00 07 00 00 00 07 00 00 00 18 00 00 00
10: 01 00 18 00 00 00 11 00 28 00 00 00 07 00 00 00
20: 07 00 00 00 01 00 18 00 00 00 00 00 a8 00 00 00
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50: 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 ff ff ff 00 20 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ff 00
80: 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 ff ff ff 00 40 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 ff ff ff 00 50 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff
c0: ff 00 60 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 ff ff ff 00 70 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 ff ff ff 00
役に立ちましたか?

解決

GetBitmapBits の代わりに GetDIBits を呼び出します。GetBitmapBits のドキュメント (ここ) は、デバイスに依存しないビットマップがあるのに対し、デバイスに依存するビットマップのデータを返していることを示します。また、この呼び出しは使用すべきではなく、16 ビット互換性のためにのみ存在することも示しています。したがって、GetDIBits を使用するとうまくいくはずです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top