トップページ > 過去ログ > 記事閲覧
GraphFilter()の縮小フィルタ
名前:pmt 日時: 2012/08/24 07:10

GraphFilter()で縮小フィルタを使用した場合についてなのですが 縮小後の画像が元々の透明部分との境界に輪郭線の様なものが出ています。 Dxライブラリは8月23日に公開されたものを使用しました。 参考 http://db.tt/rIDFip1S 上の画像では白背景に下の画像を表示しています。 透明背景に白文字というデータです。 http://db.tt/wBmnnxKi #include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { SetGraphMode( 1280 , 720, 32 ) ; ChangeWindowMode( true) ; if( DxLib_Init() == -1 ) {return -1; } int hscr = MakeScreen( 1280, 720, true) ; int hcg = LoadGraph( L"CG/bg_white1280.png" ); int hcg2 = LoadGraph( L"CG/te.png" ); SetDrawScreen( DX_SCREEN_BACK ); SetDrawBlendMode( DX_BLENDMODE_ALPHA, 255 ) ; DrawGraph( 0, 0, hcg, true );//白背景 SetDrawScreen( hscr ); DrawGraph( 0, 0, hcg2, true );//アルファ値付き画像 GraphFilter( hscr, DX_GRAPH_FILTER_DOWN_SCALE, 4 ) ;//縮小 SetDrawScreen( DX_SCREEN_BACK ); DrawGraph( 0, 0, hscr, true ); ScreenFlip() ; WaitKey() ; // キーの入力待ち((7-3)『WaitKey』を使用) DxLib_End() ; // DXライブラリ使用の終了処理 return 0 ; // ソフトの終了 } 上のコードではMakeScreen()で用意した画像を経由していますが 直接LoadGraph()で取得したハンドルに対してGraphFilter()した場合は 輪郭線は出ないようです。

Page: 1 |

Re: GraphFilter()の縮小フィルタ ( No.1 )
名前:管理人 日時:2012/08/26 00:02

輪郭線が出てしまう原因は縮小フィルタではなく描画ブレンドモードにあります ブレンドモードを DX_BLENDMODE_ALPHA を設定したときに描画先に格納される値は以下の計算式で求められます 格納される赤値 = 画像赤値 * 画像アルファ値 + 描画先赤値 * ( 1.0f - 画像アルファ値 ) 格納される緑値 = 画像赤値 * 画像アルファ値 + 描画先赤値 * ( 1.0f - 画像アルファ値 ) 格納される青値 = 画像赤値 * 画像アルファ値 + 描画先赤値 * ( 1.0f - 画像アルファ値 ) 格納されるアルファ値 = 画像アルファ値 * 画像アルファ値 + 描画先アルファ値 * ( 1.0f - 画像アルファ値 ) なんと、アルファ値はそのまま描画先に格納してほしいのに、アルファ値までアルファブレンドされてしまいます これが輪郭線が出てしまう原因です これを回避するにはブレンドモードを DX_BLENDMODE_SRCCOLOR にして描画します それによって計算式が以下のようになります 格納される赤値 = 画像赤値 * 1.0f + 描画先赤値 * 0.0f 格納される緑値 = 画像赤値 * 1.0f + 描画先赤値 * 0.0f 格納される青値 = 画像赤値 * 1.0f + 描画先赤値 * 0.0f 格納されるアルファ値 = 画像アルファ値 * 1.0f + 描画先アルファ値 * 0.0f まあ、ただ画像の色を描画先に格納しているので「ブレンド」とは言えませんが・・・ ともあれこれでアルファ値が含まれる画像を描画可能画像に描画して、それを裏画面にアルファブレンドで 描画した際も輪郭線がでないようになります ただ、この DX_BLENDMODE_SRCCOLOR を使った場合は上記式の通り描画可能画像に描画する際に アルファブレンドを行うことができません 格納されるアルファ値の計算式だけ赤・緑・青とは別にするという機能が Direct3D にはあるのですが、 まだこの機能に対応していないグラフィックスデバイスもそれなりにあるので、DXライブラリでは 使用する手段を用意していません・・・
Re: GraphFilter()の縮小フィルタ ( No.2 )
名前:pmt 日時:2012/08/29 00:48

詳しい解説ありがとうございます。 こちらの知識不足でお手数をかけてしまい申し訳ありません。 ブレンドモードの指定について勘違いしていた部分は大分理解できたと思います。 いろいろ試してみた結果、大部分は改善されたのですが GraphFilter()経由の症状はまだ残ってしまいました。 http://db.tt/VNwe8KXa int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { SetGraphMode( 1280 , 720, 32 ) ; ChangeWindowMode( true) ; if( DxLib_Init() == -1 ) {return -1; } int hscr = MakeScreen( 1280, 720, true) ; int hcg = LoadGraph( L"CG/bg_white1280.png" ); int hFont = CreateFontToHandle( L"メイリオ", 128 , 5, DX_FONTTYPE_ANTIALIASING ); SetFontSpaceToHandle( -3, hFont ) ; SetDrawScreen( DX_SCREEN_BACK ); SetDrawBlendMode( DX_BLENDMODE_SRCCOLOR, 255 ) ; DrawGraph( 0, 0, hcg, true );//白背景 SetDrawScreen( hscr ); DrawStringToHandle( 0, 0, L"テスト文字列", 0xFFEFEFEF, hFont ); GraphFilter( hscr, DX_GRAPH_FILTER_DOWN_SCALE, 2 ) ; SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 255 ) ; SetDrawScreen( DX_SCREEN_BACK ); DrawGraph( 0, 0, hscr, true ); ScreenFlip() ; WaitKey() ; // キーの入力待ち((7-3)『WaitKey』を使用) DxLib_End() ; // DXライブラリ使用の終了処理 return 0 ; // ソフトの終了 }
Re: GraphFilter()の縮小フィルタ ( No.3 )
名前:管理人 日時:2012/09/02 05:18

すみません、縮小フィルタを書けた場合の方を失念していました 輪郭線が出てしまう原因は縮小時に 「文字が描かれていない真っ黒( RGBもアルファ値も0 )のピクセルと文字が描かれている真っ黒ではないピクセルが合成される」ためです これを回避するには、描画可能画像を予め「描画文字と同じ色でアルファ値は0」で塗りつぶしておく必要があります こうすることで縮小時に文字の輪郭部分のピクセルが「真っ黒のピクセル」と合成されることはなくなります その方法ですが、DrawStringToHandle を行っている行を以下のようにします SetDrawBlendMode( DX_BLENDMODE_SRCCOLOR, 0 ) ; DrawBox( 0, 0, 1280, 720, GetColor( 0xef, 0xef, 0xef ), TRUE ) ; SetDrawBlendMode( DX_BLENDMODE_SRCCOLOR, 255 ) ; DrawStringToHandle( 0, 0, "テスト文字列", GetColor( 0xef, 0xef, 0xef ), hFont ); SetDrawBlendMode の第二引数がアルファ値となりますので、ここで0を指定して「アルファ値0」が書き込まれるようにします 次に DrawBox で画面全体を描画する文字と同じ色且つアルファ値は0で塗りつぶします これで縮小された画像も輪郭線は出なくなります よろしければお試しください
Re: GraphFilter()の縮小フィルタ ( No.4 )
名前:pmt(解決) 日時:2012/09/03 11:24

上記の方法で問題が解決したのを確認しました。 ありがとうございました。

Page: 1 |