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ライブラリを楽しく利用させていただきます。
|
|