トップページ > 記事閲覧
画像と画像の一部をブレンド
名前:名無三 日時: 2022/02/14 23:14

お世話になっております。 2Dのマップチップごとに影をブレンドするような仕組みを実装しています。 以下のように実装しているのですが、チップごとに分割画像を作ってブレンドしたら削除するプロセスをせずとも 画像と画像の一部をブレンドする方法はありますでしょうか? Vector2D_I:x,yを保持しているクラス GraphHandle:画像ハンドルのラッパー //床面に影をブレンド _p1:切り取る左上座標 _p2:切り取る右下座標 _handle:元のマップチップ m_shadow_graph:影を描画しているディスプレイサイズの画像 m_DrawPts->disp_x,m_DrawPts->disp_y:ディスプレイサイズ m_res_floor:結果のマップチップ auto& GetFloor_BlendShadow(const Vector2D_I& _p1, const Vector2D_I& _p2, GraphHandle* _handle) noexcept { const int g = DerivationGraph( std::max(0, _p1.x), std::max(0, _p1.y), std::min(m_DrawPts->disp_x, _p2.x - _p1.x), std::min(m_DrawPts->disp_y, _p2.y - _p1.y), m_shadow_graph.get()); GraphBlendBlt(_handle->get(), g, m_res_floor.get(), 128, DX_GRAPH_BLEND_NORMAL); DeleteGraph(g); return m_res_floor; }
メンテ

Page: 1 |

Re: 画像と画像の一部をブレンド ( No.1 )
名前:管理人 日時:2022/02/15 01:02

GraphBlendRectBlt ではブレンドする画像の範囲を指定することができるので、 こちらを使用すれば分割画像を作成しなくても画像と画像の一部をブレンドすることができます int GraphBlendRectBlt( int SrcGrHandle, int BlendGrHandle, int DestGrHandle, int SrcX1, int SrcY1, int SrcX2, int SrcY2, int BlendX, int BlendY, int DestX, int DestY, int BlendRatio, int BlendType, ... ) ; <GraphBlendRectBlt> https://dxlib.xsrv.jp/function/dxfunc_graph1.html#R3N31 よろしければお使いください m(_ _)m
メンテ
Re: 画像と画像の一部をブレンド ( No.2 )
名前:名無三 日時:2022/02/15 23:28

すいません、それでは画像の一部と画像のブレンドになるのではないでしょうか? 小さい画像に大きい画像の中の任意の矩形範囲をブレンドできればと思うのですが…
メンテ
Re: 画像と画像の一部をブレンド ( No.3 )
名前:管理人 日時:2022/02/16 00:04

> すいません、それでは画像の一部と画像のブレンドになるのではないでしょうか? 画像( SrcGrHandle )の一部と画像( BlendGrHandle )の一部のブレンドになります ( BlendX=0 BlendY=0 で SrcX2 - SrcX1 と SrcY2 - SrcY1 のサイズが BlendGrHandle のサイズと一致する場合は  画像の一部( SrcGrHandle の一部 )と画像全体( BlendGrHandle )のブレンドになりますが… ) > 小さい画像に大きい画像の中の任意の矩形範囲をブレンドできればと思うのですが… はい、それができるのが GraphBlendRectBlt です 具体的に使用する場合は GetFloor_BlendShadow は以下のように書き換えられると思います auto& GetFloor_BlendShadow(const Vector2D_I& _p1, const Vector2D_I& _p2, GraphHandle* _handle) noexcept { int SrcX1 = std::max(0, _p1.x); int SrcY1 = std::max(0, _p1.y); GraphBlendRectBlt( m_shadow_graph.get(), _handle->get(), g, m_res_floor.get(), SrcX1, SrcY1, SrcX1 + std::min(m_DrawPts->disp_x, _p2.x - _p1.x), SrcY1 + std::min(m_DrawPts->disp_y, _p2.y - _p1.y), 0, 0, // BlendX, BlendY 0, 0, // DestX, DestY 128, DX_GRAPH_BLEND_NORMAL ); return m_res_floor; }
メンテ
Re: 画像と画像の一部をブレンド ( No.4 )
名前:名無三 日時:2022/02/16 22:43

サンプルプログラムで動くようにしてみましたがやはりそれでは同じ描画結果が得られないのではないでしょうか…? 実行結果のスクショはこちらです。下の2枚が比較したものです。 https://drive.google.com/file/d/1O84i_oKLNLHULVDrk92Jf3oF8rf8Xa_H/view?usp=sharing #define NOMINMAX #include <algorithm> #include "DxLib.h" struct Vector2D_I { int x; int y; }; int DestHandle; //床面に影をブレンド auto& GetFloor_BlendShadow(const Vector2D_I& _p1, const Vector2D_I& _p2, int _handle, int _handle2) noexcept { int SrcX1 = std::max(0, _p1.x); int SrcY1 = std::max(0, _p1.y); GraphBlendRectBlt( _handle, _handle2, DestHandle, SrcX1, SrcY1, SrcX1 + std::min(640, _p2.x - _p1.x), SrcY1 + std::min(480, _p2.y - _p1.y), 0, 0, // BlendX, BlendY 0, 0, // DestX, DestY 128, DX_GRAPH_BLEND_NORMAL); return DestHandle; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { int SrcHandle; int BlendHandle; // DXライブラリの初期化 if (DxLib_Init() < 0) return -1; DrawBox(0, 0, 640, 480, GetColor(0, 255, 0), TRUE); // 画像を読み込む SrcHandle = LoadGraph("Src1.bmp"); // ブレンドする画像を読み込む BlendHandle = LoadGraph("Src2.tga"); // 出力先のグラフィックハンドルを作成する DestHandle = MakeScreen(128, 128, TRUE); // Handle と BlendHandle で覆い焼き合成を行う GraphBlendRectBlt( SrcHandle, BlendHandle, DestHandle, 128, 128, 256, 256, 0, 0, 0, 0, 255, DX_GRAPH_BLEND_DODGE); // 合成後の画像を画面に描画 DrawGraph(50, 50, SrcHandle, TRUE); DrawGraph(250, 50, BlendHandle, TRUE); DrawGraph(450, 50, DestHandle, TRUE); Vector2D_I P1,P2; P1.x = 0; P1.y = 0; P2.x = 128; P2.y = 128; DrawGraph(250, 250, GetFloor_BlendShadow(P1, P2, SrcHandle, BlendHandle), TRUE); DrawGraph(450, 250, GetFloor_BlendShadow(P1, P2, BlendHandle, SrcHandle), TRUE); // 読み込んだ画像のグラフィックハンドルを削除 DeleteGraph(SrcHandle); DeleteGraph(BlendHandle); // MakeScreen で作成したグラフィックハンドルの削除 DeleteGraph(DestHandle); // キー入力待ち WaitKey(); // DXライブラリの後始末 DxLib_End(); return 0; }
メンテ
Re: 画像と画像の一部をブレンド ( No.5 )
名前:管理人 日時:2022/02/17 05:35

載せていただいたプログラムの結果がどのようになれば名無三さんの意図した結果なのかは 分かりませんが、とりあえず GetFloor_BlendShadow の中身を以下のように変更しても 載せていただいたプログラムと同じ描画結果になりました auto& GetFloor_BlendShadow(const Vector2D_I& _p1, const Vector2D_I& _p2, int _handle, int _handle2) noexcept { int SrcX1 = std::max(0, _p1.x); int SrcY1 = std::max(0, _p1.y); int g = DerivationGraph( SrcX1, SrcY1, SrcX1 + std::min(640, _p2.x - _p1.x), SrcY1 + std::min(480, _p2.y - _p1.y), _handle2 ); GraphBlendBlt(_handle, g, DestHandle, 128, DX_GRAPH_BLEND_NORMAL); DeleteGraph(g); return DestHandle; } これはつまり DerivationGraph -> GraphBlendBlt -> DeleteGraph の3関数を呼ばなければならないところを GraphBlendRectBlt の1関数の呼び出しで済むことができている ( ”チップごとに分割画像を作ってブレンドしたら削除するプロセスをせずとも画像と画像の一部をブレンドできている” ) ということだと思うのですが、そうではないのでしょうか?
メンテ
Re: 画像と画像の一部をブレンド ( No.6 )
名前:名無三 日時:2022/02/17 22:46

GraphBlendBlt(SrcHandle, BlendHandle, DestHandle, 128, DX_GRAPH_BLEND_NORMAL); と GraphBlendBlt(BlendHandle, SrcHandle, DestHandle, 128, DX_GRAPH_BLEND_NORMAL); の結果は違いますのでそれでは同じ結果を得ることができないです… GraphBlendRectBltのBlendGrHandle左上、右下指定版があればと思います。 やりたいことは マップチップ1枚1枚に対して、ディスプレイサイズで作成した影画像の一部をブレンドするというものです。
メンテ
Re: 画像と画像の一部をブレンド ( No.7 )
名前:管理人 日時:2022/02/19 01:54

すみません、やっと状況が理解できました ブレンドしたい『分割画像』と『画像の一部』の大きさが同じものだと勘違いしていました ( あと GraphBlendBlt で SrcGrHandle と BlendGrHandle の大きさが異なる場合の挙動についても失念していました ) GraphBlendRectBlt の BlendGrHandle の左上、右下指定版の関数を追加しましたので、 よろしければこちらをダウンロードしてください https://dxlib.xsrv.jp/temp/DxLibVCTest.zip // Windows版 VisualC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCCTest.zip // Windows版 BorlandC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCC2Test.zip // Windows版 C++ Builder 10.3 用 https://dxlib.xsrv.jp/temp/DxLibGCC_MinGWTest.zip // Windows版 MinGW 用 https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // Windows版 .NET用 https://dxlib.xsrv.jp/temp/DxLibMakeTest.zip // ソース (中身を既存のライブラリのファイルに上書きして『リビルド』をして下さい) 以下の関数を追加しました // 二つの画像をブレンドして結果を指定の画像に出力する( 矩形指定、ブレンド画像も矩形指定 ) int GraphBlendRectBlt2( int SrcGrHandle, int BlendGrHandle, int DestGrHandle, int SrcX1, int SrcY1, int SrcX2, int SrcY2, int BlendX1, int BlendY1, int BlendX2, int BlendY2, int DestX, int DestY, int BlendRatio , int BlendType , ... ) ; GraphBlendRectBlt に BlendX2 と BlendY2 を追加しただけの関数です よろしければお試しください m(_ _)m
メンテ
Re: 画像と画像の一部をブレンド ( No.8 )
名前:名無三(解決) 日時:2022/02/20 00:35

ありがとうございます。すいません、こちらもうまく説明できませんでした…
メンテ
Re: 画像と画像の一部をブレンド ( No.9 )
名前:たろう 日時:2022/05/25 15:37

いつもありがとうございます、横から追加で失礼いたします。 GraphBlendRectBlt2を使ってみたのですが、 SrcGrHandleに入れる画像より小さい画像をBlendGrHandleに入れて試したところ BlendGrHandleの画像がバイリニアで拡大されてブレンドされるようです。 ドットゲーを作っているのですが、できればニアレストネイバーで使いたいと思います。 これは難しいでしょうか? お忙しいところすみません、よろしくお願いいたしますm(_ _)m
メンテ
Re: 画像と画像の一部をブレンド ( No.10 )
名前:たろう 日時:2022/05/25 21:32

次々とすみません、関連で質問をさせてください。 GraphBlendRectBlt2などはBltなしの直接SrcGrHandleにブレンドするバージョンがないのですが DestGrHandleのところにSrcGrHandleと同じハンドルを指定するのは正しい使い方でしょうか? そうすることで「Bltなし」と同じ結果が得られるようなので、そうしようと思っていたのですが ひょっとすると内部的に二重に画像が出来上がってしまっているのかも・・・と思いました。 ご教示いただけると幸いです。 よろしくお願いいたします。なんどもすみませんm(_ _)m
メンテ
Re: 画像と画像の一部をブレンド ( No.11 )
名前:管理人 日時:2022/05/27 01:38

> ドットゲーを作っているのですが、できればニアレストネイバーで使いたいと思います。 > これは難しいでしょうか? BlendGrHandle をバイリニアでブレンドするかニアレストでブレンドするかを設定するための関数 SetGraphBlendScalingFilterMode を追加してみましたので、よろしければこちらをダウンロードしてください m(_ _)m https://dxlib.xsrv.jp/temp/DxLibVCTest.zip // Windows版 VisualC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCCTest.zip // Windows版 BorlandC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCC2Test.zip // Windows版 C++ Builder 10.3 用 https://dxlib.xsrv.jp/temp/DxLibGCC_MinGWTest.zip // Windows版 MinGW 用 https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // Windows版 .NET用 https://dxlib.xsrv.jp/temp/DxLibMakeTest.zip // ソース (中身を既存のライブラリのファイルに上書きして『リビルド』をして下さい) 以下の関数を追加しました // GraphBlend で GrHandle と BlendGrHandle のサイズが異なる場合に適用される拡大フィルターモードを設定する // IsBilinearFilter TRUE:バイリニアフィルター(デフォルト) FALSE:ニアレストフィルター int SetGraphBlendScalingFilterMode( int IsBilinearFilter ) ; 注釈の通り引数の IsBilinearFilter を FALSE にして渡すと以降の GraphBlend系の関数で BlendGrHandle がニアレストフィルターで拡大されるようになります よろしければお試しください > GraphBlendRectBlt2などはBltなしの直接SrcGrHandleにブレンドするバージョンがないのですが > DestGrHandleのところにSrcGrHandleと同じハンドルを指定するのは正しい使い方でしょうか? はい、そのように使用していただいても問題ありません ( 私も失念していたので GraphBlend のコードを確認してみたところ、内部のブレンド関数の引数 SrcGrHandle と DestGrHandle に GrHandle を渡していたので問題無さそうです )
メンテ
Re: 画像と画像の一部をブレンド ( No.12 )
名前:たろう 日時:2022/05/29 01:06

有難うございますm(_ _)m、たろうです DestGrHandleのところにSrcGrHandleと同じハンドルを指定して大丈夫とのことで安心しました。 また、SetGraphBlendScalingFilterModeを追加していただき有難うございます。 先程確認して、望み通りの結果が得られました。 その上ですみません、一つ気づいてしまったので追加で質問させてくださいm(_ _)m GraphBlendRectBlt2を使って、画像Aにその半分の大きさの画像Bをブレンドしようと考え GraphBlendRectBlt2(A,B,A,0,0,(Aの横幅),(Aの縦幅),0,0,(Bの横幅),(Bの縦幅),0,0,255,DX_GRAPH_BLEND_PMA_MULTIPLE_A_ONLY); としたところその通りの結果が得られて満足していたのですが、試しに GraphBlend(A,B,255,DX_GRAPH_BLEND_PMA_MULTIPLE_A_ONLY); とそのままブレンド位置指定無しのブレンドで試したところ、同じようにBが2倍に拡大されAにブレンドされました。 これはつまりGraphBlendで違う大きさの画像をブレンドすると、特に四隅を位置指定せずとも 必ずSrcGrHandleと同じ大きさにBlendGrHandleが引き伸ばされて ブレンドされるという事でしょうか? よろしくお願いいたしますm(_ _)m
メンテ
Re: 画像と画像の一部をブレンド ( No.13 )
名前:管理人 日時:2022/05/29 20:58

> これはつまりGraphBlendで違う大きさの画像をブレンドすると、特に四隅を位置指定せずとも > 必ずSrcGrHandleと同じ大きさにBlendGrHandleが引き伸ばされて > ブレンドされるという事でしょうか? はい、その通りです
メンテ
Re: 画像と画像の一部をブレンド ( No.14 )
名前:たろう(解決) 日時:2022/05/29 22:55

以前試して拡大されなかったような気がしていたので GraphBlendRectBlt2導入に伴う変更なのかと勘違いしました。 仕様との事で安心です。 ありがとうございましたm(_ _)m
メンテ

Page: 1 |

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

   クッキー保存