「RotateTransparentAlphaBlt」の編集履歴(バックアップ)一覧はこちら
RotateTransparentAlphaBlt - (2011/11/09 (水) 09:23:45) の1つ前との変更点
追加された行は緑色になります。
削除された行は赤色になります。
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に渡す引数もそれに合わせている。
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に渡す引数もそれに合わせている。
ただし、この関数での描画は時間がかかる([[時間比較]]参照)ため、場合に応じて使い分ける必要がある。
表示オプション
横に並べて表示:
変化行の前後のみ表示: