frostar@wiki

メニュー

作ったもの

過去の遺物
TRPG
プログラム
リンク

自分関係

ここのページへのリンクについてはこちら
TRPGのセッション記録とかメインのブログ
生配信チャンネル。プログラム<雑談
気が向いたときにやります
個人的な質問に答えてます。

TRPG系

お世話になっているオンラインセッションサイト
TRPGのことならここ!
IRCサーバなど、お世話になってます。
ネクロニカの支援サイトです。ツール開発やオンセもやっています。

プログラム系

初心者のためのプログラムのページ。WindowsSDKの方についても詳しく書いています。
windowsSDKのテクニックがいろいろ書いてあります。
C++STL(標準テンプレートライブラリ)の日本語版リファレンスです。


更新履歴

取得中です。


RotateTransparentAlphaBlt


※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

TransparentAlphaBlt、RotateBltを合わせた関数、RotateTransparentAlphaBltを作成する。
つまり、この関数1つで拡大縮小、回転、背景色透過、半透明合成などが実現できます。
以下、ソースコード。
BOOL RotateTransparentAlphaBlt(
HDC hdcDest,//描画先HDC
int DestX,//描画先長方形左上X座標
int DestY,//描画先長方形左上Y座標
int DestW,//描画先長方形幅
int DestH,//描画先長方形高さ
HDC hdcSrc,//描画元HDC
int SrcX,//描画元長方形左上X座標
int SrcY,//描画元長方形左上Y座標
int SrcW,//描画元長方形幅
int SrcH,//描画元長方形高さ
int rad,//回転角度(ラジアン単位)
COLORREF Transparent,//透過色
int Alpha//不透明度
){
//回転時の最大サイズに合わせてHDC初期化
int d = sqrt(pow(DestW,2.0)+pow(DestH,2.0));
HDC RTAhdc;
HBITMAP hDummy;
RTAhdc = CreateCompatibleDC(NULL);
hDummy = CreateCompatibleBitmap(hdcDest,d,d);
SelectObject(RTAhdc,hDummy);
DeleteObject(hDummy);
//初期化したHDCを透過色で塗りつぶす
RECT rc;
rc.left = 0;
rc.top = 0;
rc.right = d;
rc.bottom = d;
HBRUSH hbrush;
hbrush=CreateSolidBrush(Transparent);
FillRect(RTAhdc,&rc,hbrush);
DeleteObject(hbrush);
//回転
if(FALSE==RotateBlt(RTAhdc,(d-DestW)/2,(d-DestH)/2,DestW,DestH,hdcSrc,SrcX,SrcY,SrcW,SrcH,rad)){
	DeleteDC(RTAhdc);
	return FALSE;
}
//透過色と半透明合成
if(FALSE==TransparentAlphaBlt(hdcDest,DestX-(d-DestW)/2,DestY-(d-DestH)/2,d,d,
	RTAhdc,0,0,d,d,Transparent,Alpha)){
	DeleteDC(RTAhdc);
	return FALSE;
}
DeleteDC(RTAhdc);
return TRUE;
}

まず、描画用のHDCを初期化する。このHDCには描画元の画像を回転させた画像を描画することになる。そのため、描画元の画像と同じサイズで初期化してしまうと、回転時にはみ出してデータが消えてしまう部分が生じる可能性がある。
そこで、描画元の√x^2+y^2のサイズで初期化する。これは長方形の対角線の式であり、対角線の長さで(X,Y両方)初期化することで回転した時に対角線の大きさより大きくはみ出る場所はないため、データの消失を防ぐことができる。
そうして、初期化したHDCを今度は透過色で塗りつぶす。
このHDCに描画元の画像を回転させて描画し、さらにそれを透過、半透明合成することでこの関数を実現する。
ただし、先ほどのようにデータの消失を防ぐために、回転時には中央に描画するようにしている((d-DestW)/2,(d-DestH)/2)。
また、TransparentAlphaBltに渡す引数もそれに合わせている。
ただし、この関数での描画は時間がかかる(描画関数の時間比較参照)ため、場合に応じて使い分ける必要がある。