CreateDIBSection()でモノクロのビットマップを作成するには?

解決


sel  2009-05-15 21:28:24  No: 70156

お世話になります。
MaskBlt()でマスクに使用するビットマップを作成したいのですが、
CreateBitmap()でbpp=1にして作成すると正常に動作します。
しかしこれではビット操作がしづらいので、
CreateDIBSection()を使用したいと思い、同様にbpp=1で作成した所、
どう設定してもきちんとマスクができませんでした。

CreateDIBSection()ではMaskBlt()用のモノクロビットマップは作成できないのでしょうか?
ぐぐっても、この2つの関係について言及している所は見つかりませんでした。
よろしくお願いします。


  2009-05-15 21:55:43  No: 70157

どうしても
きちんと出来ません
ではなく説明して欲しい


sel  2009-05-15 22:19:12  No: 70158

失礼しました。コーディングはだいたい以下のようになっています。

1.BITMAPINFOHEADER は概ね下のように設定。
  bih.biPlanes = 1;
  bih.biWidth = width;
  bih.biHeight = height;
  bih.biBitCount = 1;
  bih.biCompression = BI_RGB;

2.BITMAPINFO::bmiColors は2個分確保して下のように設定。
  long  white = RGB(255,255,255);
  long  black = RGB(0,0,0);
  CopyMemory(&bi.bmiColors[0], &white, sizeof(RGBQUAD));
  CopyMemory(&bi.bmiColors[1], &black, sizeof(RGBQUAD));

3.マスク用ビットマップ作成
  hBmp = CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, (void**)&pData, NULL, 0);

4.描画
  MaskBlt(hDest, xDest, yDest, width, height, hSrc, xSrc, ySrc
      , hBmp, 0, 0, MAKEROP4(SRCCOPY, PATCOPY));

3で作成したマスク用ビットマップが、きちんと白黒で描画されるのは確認しました。
しかし4の描画結果は、マスクが反映されず、全体が描画されているようです。


sel  2009-05-16 00:39:06  No: 70159

自己解決しました。
MaskBlt()の最後の引数を MAKEROP4(SRCCOPY, SRCAND) に変更すると
マスクをかけて描画できました。
PATCOPYじゃだめだったんですね・・・。
なんとなく釈然としないような気もしますが。

ちなみに、上レスの2に関しては、特に必要ありませんでした。
MaskBlt()は、パレットの色がどんな色であろうと関係なく、各ピクセルが0か1かで判定してくれるようです。


gak  2009-05-16 02:27:22  No: 70160

> なんとなく釈然としないような気もしますが
raster operation に関する項目を見直してみると良いかと。

> MAKEROP4(SRCCOPY, PATCOPY)
background rop として PATCOPY を指定した場合、↓のように動作する。
・"マスク用モノクロイメージのビットが立っていない位置に該当する" hDest 上のピクセルを、hDest に選択されたブラシで塗り潰す

> MAKEROP4(SRCCOPY, SRCAND)
background rop として SRCAND を指定した場合、↓のように動作する
・"マスク用 (ry〜 に該当する" hDest 上のピクセルの色と、"マスク用 (ry〜 に該当する" hSrc 上のピクセルの色を論理積する

> MAKEROP4(SRCCOPY, SRCAND) に変更するとマスクをかけて描画できました
確信を持っているワケではないが hSrc の内容によっては SRCAND では問題があるかもしれない。
例えば、hDest の "マスク用 (ry〜 に該当する" 位置の色が RGB(0x80, 0x80, 0x80) とした場合、
・hSrc の "マスク用 (ry〜 に該当する" 位置の色が RGB(0xff, 0xff, 0xff) 
  処理後の色 = RGB(0x80 & 0xff, 0x80 & 0xff, 0x80 & 0xff) = RGB(0x80, 0x80, 0x80)
  となり hDest の色に変化は起こらない。
・hSrc の "マスク用 (ry〜 に該当する" 位置の色が RGB(0x00, 0x00, 0x00) 
  処理後の色 = RGB(0x80 & 0x00, 0x80 & 0x00, 0x80 & 0x00) = RGB(0x00, 0x00, 0x00)
  となり、処理後の色は元の hDest の色と変わってくる。

という風に hSrc の内容によって結果が違ってくる。
# hSrc のマスク該当位置の色は必ず RGB(0xff, 0xff, 0xff) という前提が成り立つなら SRCAND で良いのだけどね


sel  2009-05-16 02:59:42  No: 70161

レスありがとうございます。
MSDNも見てはみたのですが、SRCANDはまだしもPATCOPYに関しては

・指定したパターンをコピー先にコピーします。

という文章だけでいまいちわからず、とりあえず猫でも〜でやってるからこれでいいだろうと
ちょっとスルーしてました・・・。

指摘していただいた問題点ですが、確かに考えてみるとそうですよね。
実際不安なのでマスクやソースの色をいろいろ変えて試してみたのですが
結果としてはどんな色でも同じように問題なく描画されました。
おそらく MaskBlt() がオフビットは0xFF、オンビットは0x00として処理してくれているぽいですね。
とはいえ念のため、パレットも初期化しておくことにします。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加