トップページ > 記事閲覧
画像の一部に穴をあけて表示する
名前:Ketty 日時: 2024/12/17 15:54

管理人様 いつも楽しくDXライブラリを利用させていただいています(^^) 質問させてください。 画像(グラフィックハンドル)に、DrawCircleで描画した円を合成し、 円の部分だけを透明にした画像を描画する、ということは可能でしょうか? やりたいこととしては、画像の一部を穴あきにして、そこから背景が覗き込めるようなことをしたく、 その際に、穴の大きさや位置を、プログラムで動的に制御できないかと考えています。 ↓こちらも参考にさせていただきましたが、こちらは穴も画像でご用意されるやり方だという認識です。 https://dxlib.xsrv.jp/cgi/patiobbs/patio.cgi?mode=view&no=4512 お手数をおかけしますがよろしくお願いします。
メンテ

Page: 1 |

Re: 画像の一部に穴をあけて表示する ( No.1 )
名前:管理人 日時:2024/12/18 00:41

> 画像(グラフィックハンドル)に、DrawCircleで描画した円を合成し、 > 円の部分だけを透明にした画像を描画する、ということは可能でしょうか? はい、GraphBlendBlt を使用すると可能です 手順としては、穴開きにしたい画像と同じサイズの画像を MakeScreen で2つ作成して、 その画像の一つに対してまず全体を真っ白で塗りつぶし、その後穴開きにしたい箇所に DrawCircle を使用して黒色の円を描画します そして GraphBlendBlt で『穴開きにしたい画像』と『穴開きにしたい箇所以外が真っ白になっている画像』を 合成して『穴開きにしたい箇所だけアルファ値が0になっている画像』を作成します 後はそれを DrawGraph で描画するだけです サンプルを組んでみましたのでよろしければ参考にしてください m(_ _)m ( 下記サンプルでは『穴開きにしたい画像』が無いので LoadGraph で読み込む代わりに MakeScreen で 画像に見立てたものを作成しています ) #include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int x = 0, add = 8 ; // ウインドウモードで起動 ChangeWindowMode( TRUE ) ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) return -1 ; // 描画先を裏画面にする SetDrawScreen( DX_SCREEN_BACK ) ; int Graph = MakeScreen( 640, 480, TRUE ) ; int AlphaScreen = MakeScreen( 640, 480, TRUE ) ; int BlendScreen = MakeScreen( 640, 480, TRUE ) ; // Graph は全体を緑色でクリア SetDrawScreen( Graph ) ; DrawBox( 0, 0, 640, 480, GetColor( 0,255,0 ), TRUE ) ; SetDrawScreen( DX_SCREEN_BACK ) ; // メインループ while( ProcessMessage() == 0 ) { // 移動 x += add ; if( x < 0 || x > 640 ) add = -add ; // 画面を赤色でクリア DrawBox( 0, 0, 640, 480, GetColor( 255,0,0 ), TRUE ) ; // AlphaScreen 全体を白で塗りつぶした後 x, 240 の座標に黒い円を描く SetDrawScreen( AlphaScreen ) ; DrawBox( 0, 0, 640, 480, GetColor( 255,255,255 ), TRUE ) ; DrawCircle( x, 240, 64, GetColor( 0, 0, 0 ), TRUE ) ; SetDrawScreen( DX_SCREEN_BACK ) ; // Graph と AlphaScreen をブレンドする( 赤・緑・青成分は Graph から、アルファ値は AlphaScreen の赤成分から取得 ) GraphBlendBlt( Graph, AlphaScreen, BlendScreen, 255, DX_GRAPH_BLEND_RGBA_SELECT_MIX, DX_RGBA_SELECT_SRC_R, DX_RGBA_SELECT_SRC_G, DX_RGBA_SELECT_SRC_B, DX_RGBA_SELECT_BLEND_R ) ; // 画面に BlendScreen を描画 DrawGraph( 0, 0, BlendScreen, TRUE ) ; // 裏画面の内容を表画面に反映 ScreenFlip() ; } // DXライブラリの後始末 DxLib_End() ; // ソフトの終了 return 0 ; }
メンテ
Re: 画像の一部に穴をあけて表示する ( No.2 )
名前:Ketty 日時:2024/12/18 18:07

管理人さま さっそくお返事ありがとうございますm(_ _m ご教示いただいたやり方で画像の一部を穴あきにできることを確認できました(^^) 恐れ入りますが、追加で質問させてください。 透過色(255,0,255)を指定したうえで、 下記のような画像で穴あき合成をしようとしております。 <画像です> https://ibb.co/bbVwL51 穴あきは実現されたものの、画像のR:255,G:0,B:255部分が黒く表示されてしまいます。 この部分の透過を崩さずにするにはどのようにすればよいのでしょうか? 以下はソースコードです。 -------------------------------------- #include <DxLib.h> // 画像のサイズ int GRAPH_SIZE_X = 64; int GRAPH_SIZE_Y = 64; // Main関数 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // ログ出力設定 DxLib::SetOutApplicationLogValidFlag(FALSE); DxLib::SetUseDateNameLogFile(TRUE); // ウィンドウモードの設定 DxLib::ChangeWindowMode(TRUE); // DXライブラリ初期処理 if (DxLib::DxLib_Init() == -1) { return -1; } // 透過色を指定 DxLib::SetTransColor(255, 0, 255); // 透過色(255,0,255)を持った画像をロード DxLib::SetUsePremulAlphaConvertLoad(TRUE); int Graph = DxLib::LoadGraph("pic.png"); DxLib::SetUsePremulAlphaConvertLoad(FALSE); // 合成用のグラフィックハンドルを作る int AlphaScreen = MakeScreen(GRAPH_SIZE_X, GRAPH_SIZE_Y, TRUE); int BlendScreen = MakeScreen(GRAPH_SIZE_X, GRAPH_SIZE_Y, TRUE); // AlphaScreen 全体を白で塗りつぶした後 16, 16 の座標に黒い円を描く DxLib::SetDrawScreen(AlphaScreen); DxLib::DrawBox(0, 0, GRAPH_SIZE_X, GRAPH_SIZE_Y, DxLib::GetColor(255, 255, 255), TRUE); DxLib::DrawCircle(16, 16, 8, DxLib::GetColor(0, 0, 0), TRUE); // 穴開きにしたい箇所だけアルファ値が0になっている画像を作る // 元画像 と 円 をブレンドする(赤・緑・青成分は Graph から、アルファ値は 円 の赤成分 から取得 ) DxLib::GraphBlendBlt(Graph , AlphaScreen , BlendScreen , 255 , DX_GRAPH_BLEND_RGBA_SELECT_MIX , DX_RGBA_SELECT_SRC_R , DX_RGBA_SELECT_SRC_G , DX_RGBA_SELECT_SRC_B , DX_RGBA_SELECT_BLEND_R); // 描画先を裏画面にする DxLib::SetDrawScreen(DX_SCREEN_BACK); // 背景色を灰色にする DxLib::SetBackgroundColor(128, 128, 128); // ESCキーで終了 while (DxLib::ProcessMessage() == 0 && DxLib::CheckHitKey(KEY_INPUT_ESCAPE) == 0) { DxLib::ClearDrawScreen(); // 合成した画像を描画 DxLib::DrawGraph(0, 0, BlendScreen, TRUE); // フリップして裏画面の内容を表画面に出力 DxLib::ScreenFlip(); // 少し待つ ::Sleep(16); } // DXライブラリ終了処理 DxLib::DxLib_End(); // ソフトの終了 return 0; } ----------------------------------------- 環境など Windows10 Pro Visual Studio 2017 Commity DXライブラリのバージョンは、下記でご提示いただいたテスト版です https://dxlib.xsrv.jp/cgi/patiobbs/patio.cgi?mode=view&no=5716 お手数をおかけしますがよろしくお願いいたします。
メンテ
Re: 画像の一部に穴をあけて表示する ( No.3 )
名前:管理人 日時:2024/12/20 03:59

LoadGraph で読み込まれた画像の透過色の部分はアルファ値( 不透明度 )が 0 に置き換えられますので 前回の処理に加えて『穴開きにしたい画像』のアルファ値と BlendScreen のアルファ値を乗算するという処理を追加するとご希望の処理を実現できます 1.穴開きにしたい画像( 仮に D )と同じサイズの画像を MakeScreen で3つ作成します( 仮に E, F, H とします、一つ作る画像が増えています ) 2.MakeScreen で作成した3つの画像の一つ E に対してまず全体を真っ白で塗りつぶし、   その後穴開きにしたい箇所に DrawCircle を使用して黒色の円を描画します( ここは特に変更無しです ) 3.次に GraphBlendBlt でブレンドタイプ DX_GRAPH_BLEND_RGBA_SELECT_MIX を使用して、R, G, B, A をそれぞれ   R = E の R、 G = E の G、 B = E の B、 A = E の R  としたものを F に出力します 4.次に GraphBlendBlt でブレンドタイプ DX_GRAPH_BLEND_MULTIPLE_A_ONLY を使用して、D の A と F の A を乗算したものを H に出力します( R, G, B は D のものとなります ) 5.H を画面に描画します No.2 で載せていただいたコードを上記手順のものになるように少し変更すると以下のようになりますので   よろしければ参考にしてください m(_ _)m #include <DxLib.h> // 画像のサイズ int GRAPH_SIZE_X = 64; int GRAPH_SIZE_Y = 64; // Main関数 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // ログ出力設定 DxLib::SetOutApplicationLogValidFlag(FALSE); DxLib::SetUseDateNameLogFile(TRUE); // ウィンドウモードの設定 DxLib::ChangeWindowMode(TRUE); // DXライブラリ初期処理 if (DxLib::DxLib_Init() == -1) { return -1; } // 透過色を指定 DxLib::SetTransColor(255, 0, 255); // 透過色(255,0,255)を持った画像をロード DxLib::SetUsePremulAlphaConvertLoad(TRUE); int Graph = DxLib::LoadGraph("pic.png"); DxLib::SetUsePremulAlphaConvertLoad(FALSE); // 合成用のグラフィックハンドルを作る int AlphaScreen = MakeScreen(GRAPH_SIZE_X, GRAPH_SIZE_Y, TRUE); int BlendScreen = MakeScreen(GRAPH_SIZE_X, GRAPH_SIZE_Y, TRUE); int MulScreen = MakeScreen(GRAPH_SIZE_X, GRAPH_SIZE_Y, TRUE); // AlphaScreen 全体を白で塗りつぶした後 16, 16 の座標に黒い円を描く DxLib::SetDrawScreen(AlphaScreen); DxLib::DrawBox(0, 0, GRAPH_SIZE_X, GRAPH_SIZE_Y, DxLib::GetColor(255, 255, 255), TRUE); DxLib::DrawCircle(16, 16, 8, DxLib::GetColor(0, 0, 0), TRUE); // 穴開きにしたい箇所だけアルファ値が0になっている画像を作る // (赤・緑・青成分は 円 から、アルファ値は 円 の赤成分 から取得 ) DxLib::GraphBlendBlt(AlphaScreen , AlphaScreen , BlendScreen , 255 , DX_GRAPH_BLEND_RGBA_SELECT_MIX , DX_RGBA_SELECT_SRC_R , DX_RGBA_SELECT_SRC_G , DX_RGBA_SELECT_SRC_B , DX_RGBA_SELECT_SRC_R); // アルファチャンネルの乗算 DxLib::GraphBlendBlt(Graph , BlendScreen , MulScreen , 255 , DX_GRAPH_BLEND_MULTIPLE_A_ONLY ); // 描画先を裏画面にする DxLib::SetDrawScreen(DX_SCREEN_BACK); // 背景色を灰色にする DxLib::SetBackgroundColor(128, 128, 128); // ESCキーで終了 while (DxLib::ProcessMessage() == 0 && DxLib::CheckHitKey(KEY_INPUT_ESCAPE) == 0) { DxLib::ClearDrawScreen(); // 合成した画像を描画 DxLib::DrawGraph(0, 0, MulScreen, TRUE); // フリップして裏画面の内容を表画面に出力 DxLib::ScreenFlip(); // 少し待つ ::Sleep(16); } // DXライブラリ終了処理 DxLib::DxLib_End(); // ソフトの終了 return 0; }
メンテ
Re: 画像の一部に穴をあけて表示する ( No.4 )
名前:Ketty(解決) 日時:2024/12/20 12:55

管理人さま 丁寧にご説明くださりありがとうございます(^^) おかげさまで理解できました。 また、やりたかったことも実現できましたので解決とさせていただきます。 これからもDXライブラリを楽しく利用させていただきます。
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存