::AlphaBlend を使用した半透明処理について – プログラミング – Home

::AlphaBlend を使用した半...
 
通知
すべてクリア

[解決済] ::AlphaBlend を使用した半透明処理について


紅
 紅
(@紅)
ゲスト
結合: 17年前
投稿: 1
Topic starter  

こんにちわ。紅'と申します。
半透明処理についてご教示ください。

環境は VISTA & VC2008( WIN32 / MFC ) です。
以下のコードは、作成済みイメージの特定部位に、半透明処理を利用して薄い色を被せ
る(つもり)で作成しました。
EXCEL などの選択中セルをイメージしていただけるとわかりやすいと思います。

現状では、上記の「薄い色」が表示されず、実行前後で描画されるイメージに変化があ
りません。
コメントアウトしてある BitBlt を有効にすると「薄い色」を表示したい部分が指定し
た色で
塗りつぶされます。また、CImage::AlphaBlend を使用するとイメージ通りに描画されま
す。

色々と試したつもりですが、原因が分かりません。
原因と思われる箇所などをご指摘いただけると嬉しく思います。

{
REC tWorkRect = (描画域取得);
HBITMAP hTranseBitmap = ::CreateCompatibleBitmap( (描画先HDC),
tWorkRect.right, tWorkRect.bottom );
HDC hTranseContext = ::CreateCompatibleDC( (描画先
HDC) );
HBRUSH hBrush = ::CreateSolidBrush( (描画色取
得) );

::SelectObject( hTranseContext, hTranseBitmap );
::FillRect( hTranseContext, &tWorkRect, hBrush );

BLENDFUNCTION tBlendData;
::memset( &tBlendData, 0, sizeof( tBlendData ) );
tBlendData.BlendOp = AC_SRC_OVER;
tBlendData.BlendFlags = 0;
tBlendData.SourceConstantAlpha = (BYTE)( 255.0f * 0.2 );
tBlendData.AlphaFormat = AC_SRC_ALPHA;

::AlphaBlend( (描画先HDC), tWorkRect.left, tWorkRect.top,
tWorkRect.right, tWorkRect.bottom,
hTranseContext, tWorkRect.left,
tWorkRect.top, tWorkRect.right, tWorkRect.bottom, tBlendData );
// ::BitBlt( (描画先HDC), tWorkRect.left, tWorkRect.top,
tWorkRect.right, tWorkRect.bottom,
// hTranseContext, tWorkRect.left, tWorkRect.top,
SRCCOPY );

::SelectObject( hTranseContext, (HBRUSH)NULL );
::DeleteObject( hBrush );
hBrush = NULL;

::SelectObject( hTranseContext, (HBITMAP)NULL );
::DeleteObject( hTranseBitmap );
hTranseBitmap = NULL;

::DeleteDC( hTranseContext );
hTranseContext = NULL;
}

なお、上記のコードは、実際に作成した物から不要部分を除去するなどの手を入れてい
るため
基本的な誤りがあるかもしれませんが、一応、実際の環境ではコンパイルを通し、前述
した程度の動作の
確認を行っています。

以上、よろしくお願いいたします。


引用未解決
トピックタグ
紅'
 紅'
(@紅')
ゲスト
結合: 17年前
投稿: 48
 

改行位置が悪かったようです。見づらくてすみません。
あと、名前欄の入力をミスっていました。「紅'」です。重ねてすみません。


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

CImage::AlphaBlend のソースを追いかけてみましたが、CImage::Create のフラグに
createAlphaChannel が指定されていない場合、AlphaFormat が 0 になっていますね。
で、あらためて BLENDFUNCTION のドキュメントを見てみると、

> When the AlphaFormat parameter is AC_SRC_ALPHA,
> the source bitmap must be 32 bpp. If it is not,
> the AlphaBlend function will fail.

とか書いてあります。
AlphaBlend function will fail とか書いてあるくせに、戻り値が 1 を返すのがむかつ
きます。

> If the source bitmap has no per-pixel alpha value
> (that is, AC_SRC_ALPHA is not set),

という記述があることからも、AlphaFormat は必ず AC_SRC_ALPHA でなければならないと
いうことはないようですが、0 にすべしとも書いてないのは不親切ですね。

というわけで、AlphaFormat は 0 にするのが正解のようです。


返信引用
gak
 gak
(@gak)
ゲスト
結合: 21年前
投稿: 132
 

AlphaFormat に AC_SRC_ALPHA を指定するケースというのは
・bitmap が bgra(blue, green, red, alpha)で構成されている時
だけだね。
bitmapにalpha値が存在しない(==32bppのbitmapでない)or alpha値を利用しない場合は
指定しない。

> AlphaBlend function will fail とか書いてあるくせに、戻り値が 1 を返す
こっちの環境で(screenとコンパチブルな)16 bpp のbitmap同士で AC_SRC_ALPHA を指
定して AlphaBlend() を試してみたら一応 0 が返ってきたね。
16bpp以外は試していないので上記以外のケースでどうなるかは判らないけど。

> 0 にすべしとも書いてないのは不親切ですね。
めちゃ同意。
「AlphaFormat has the following value」とあり、following value として
AC_SRC_ALPHA しか載せていない現在のMSDNでは誤解してしまう。


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

>> AlphaBlend function will fail とか書いてあるくせに、戻り値が 1 を返す
> こっちの環境で(screenとコンパチブルな)16 bpp のbitmap同士で
> AC_SRC_ALPHA を指定して AlphaBlend() を試してみたら一応 0 が返ってきたね。

追試サンクス。

俺が実験したときは、画面のプロパティが 32bit になっていたので、変な形で成功して
いたのかもしれない。


返信引用
紅'
 紅'
(@紅')
ゲスト
結合: 17年前
投稿: 48
 

シャノンさん、gak さん、返信をありがとうございます。

試したところ出来ました。感謝します。
MSDN に嘘?が書いてあるって...

この辺りのパラメータは一応いじってみてはいたのですが、
組み合わせが悪かったようです。CImage の作りなど、なにか深そう?ですし、
会社ではやれませんがw週末など暇を見つけて追ってみようと思います。

MFC の中を追ってみるという考えが最近なぜか抜けていました。
こちらも反省点でした。

ありがとうございました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました