ピクチャボックスに画面キャプチャしたビットマップをセットし、同ピクチャボックスの背景を変更すると、ビットマップの一部の色も変更されてしまう

[戻る]
ナトゥ 2009/12/15(火) 21:46:43
VisualStudio 2005 MFCです。

ダイアログを親ウィンドウとし、ピクチャボックスを貼り付けます。
そこに、画面キャプチャした画像(メモリDCとBitBltを使用し作成)を
HBITMAPとして格納し、SetBitmapでピクチャボックスに設定します。

その後、親ウィンドウのOnCtlColor()でピクチャボックスの背景を変更すると、
ビットマップの一部(ウィンドウのグレーの部分<::GetSysColor(COLOR_MENU)と同色>)が
変更した背景色と同じ色に変更されてしまいます。

どうも、ビットマップのグレーの部分<::GetSysColor(COLOR_MENU)と同色>が
マスクされて背景として塗りつぶされてしまっているようなのですが、
このようにビットマップの一部を塗りつぶさずに、
同ピクチャボックスの背景色を変更する方法はないでしょうか?

2009/12/15(火) 22:58:01
描画前に背景色で塗りつぶしてしまうというのはどうでしょう?
ピクチャボックスの背景なら別に無理にCTLCOLORで処理する必要はないと思いますが

ナトゥ 2009/12/16(水) 09:32:19
CStaticを派生させたピクチャコントロールクラスを作成し、
SetBitmap()前に、同クラスのOnPaint()内でFillRect()しましたが、
ピクチャコントロールの背景色が変更されませんでした。
何かやり方が間違っているのでしょうか?

しかも、派生ピクチャコントロールクラスのOnPaint()を
オーバーライドすると、SetBitmap()したビットマップが
全く表示されなくなってしまいました。
#特にOnPaint内に処理は記述していません。。。

仲澤@失業者 2009/12/16(水) 09:53:34
一応、元の Static Ctrl のプロパティの「Transparent」属性がFalseに
なっていることを確認してみましょう。
上記がFalseなのに透過してしまうのなら、OnPaintをオーバーライドして
自前で描画するしかありません。
しかし、ここまでやるのなら、
自前のコントロールにしてしまった方が後々楽かもしれません。

2009/12/16(水) 12:03:27
SetBitmap()で関連付けられたビットマップってどういう扱い受けるんでしょうね…
根本的な解決にはならないかもしれませんが、
BitBlt()もしくはStretchBlt()を使うのもありだと思います。

bun 2009/12/16(水) 13:05:54
全ての疑問の前に、1つの謎が、

ピクチャーボックスにSetBitmap()するということは、
ピクチャーボックス全体がビットマップで塗りつぶされると言うことですよね?

背景なんて、全部塗りつぶされてしまって見えないから、
ピクチャボックスの背景色を議論する意味が不明。

なんか私の勘違いでしょうか?

gak 2009/12/17(木) 17:21:48
> なんか私の勘違いでしょうか?
今回の件と関係あるかは不明だけど、XPのVisualスタイル相当のものが有効な環境だとピ
クチャボックスに SetBitmap された画像のα値は適用される。この場合背景が絡んでくる。

α適用に関する直接的な資料は見つけられなかったのだけど、「α付きの場合はちょっと動
作が変わるよ」程度の情報ならあった。
http://msdn.microsoft.com/en-us/library/bb760782%28VS.85%29.aspx

> マスクされて背景として塗りつぶされてしまっているようなのですが
もしかしたら、ナトゥさんが SetBitmap した HBITMAP にはα値が存在していたのかもし
れないね。BitBlt の SRC**** 系処理はα値もコピーする動作だった筈なので、キャプ
チャ元にα情報が存在していた場合はα値もコピーされていたのかもしれない。

ITO 2009/12/18(金) 10:53:45
http://msdn.microsoft.com/ja-jp/library/b7w5x74z(VS.80).aspx
MSDN読んだ?
解説に、

-------- ココカラ ----------
>SS_CENTERIMAGE   
>  静的コントロールの中央に揃えるのに使います。
>  イメージが静的コントロールより大きいときは、クリッピングされます。
>  静的コントロールより小さいときは、イメージの周囲の空の領域は
>  ビットマップの左上隅のピクセルの色で塗りつぶされます。
-------- ココマデ ----------
とあり、
>  ビットマップの左上隅のピクセルの色で塗りつぶされます。
ですよね。

ナトゥ 2009/12/18(金) 16:45:33
皆様ご回答ありがとうございます。

> bunさん
> 背景なんて、全部塗りつぶされてしまって見えないから、
> ピクチャボックスの背景色を議論する意味が不明。
CStaticの派生クラスを動的にSS_BITMAPの属性を付加した上で
サイズを指定してCreate()すると、SetBitmapを行っても、
作成したコントロールはBitmapのサイズにリサイズされずに、
背景が現われてきます。そこで、この背景を何とかしようと
考えていました。

>ITOさん
本件で問題としているのは、同Staticコントロールの背景色を変更すると、
ビットマップ内部の一部の色も変更されてしまうという内容です。
指摘の通り、余白が塗りつぶされることは確認できています。

>gak
α値の件はまだ理解不足なのですが、gakさんがおっしゃるような
何らかの現象がおきているような気が私もしています。

とりあえず、今回は作成するStaticコントロールをSS_BITMAPとせず、
直接このコントロールのDCにビットマップを描画して対応する予定です。

ナトゥ 2009/12/21(月) 12:37:38
[[解決]]
解決チェックを忘れてしまいました。

古いスレッドには追加発言できません。