トップページ > 記事閲覧
GetDrawScreenSoftImage について
名前:tripper 日時: 2016/02/17 16:58

いつもDXライブラリを愛用させて頂いております 軽量化のためにスプライトシートのようなものを自動生成しようと思い至り MakeScreen, MakeARGB8ColorSoftImage, GetDrawScreenSoftImage, SaveSoftImageToPng などを用いて プログラム内で読み込んだ画像をすべて複数枚の大きな画像にまとめて吐き出すコードを書いていたところ 生成された画像と元画像が異なるものになっていました テストに用いたコード rumia.hungry.jp/dxlibtest/spriteExportTestCode.txt テストに用いた画像 rumia.hungry.jp/dxlibtest/1_original.png (2_original.png も) テスト結果 rumia.hungry.jp/dxlibtest/result1.png (result5.png まであります) DrawSoftImage で描画した時点で色やアルファ値が異なるものになっているようです 環境の問題、使用している画像の問題、仕様などでしたら大変申し訳ありません 仕様、もしくは不具合であった場合で修正が困難/不可能ということであれば とても不躾なお願いではありますが代替案も教えて頂ければ大変助かります 使用中のDXライブラリのバージョンは 3.16 開発環境は Visual Studio 2013 Community を使用しています よろしくお願いいたします
メンテ

Page: 1 |

Re: GetDrawScreenSoftImage について ( No.1 )
名前:管理人 日時:2016/02/21 04:27

生成された画像と元画像が同じになるようにアップして頂いたコードに少し 処理を追加してみましたので、よろしければご覧ください m(_ _)m void ExportSingleSprite(int spriteHandle, const char* filePath){ char defaultFilePath[65535]; int scrHandle, sImgHandle; int xSize, ySize; GetGraphSize(spriteHandle, &xSize, &ySize); scrHandle = MakeScreen(xSize, ySize, TRUE); SetDrawScreen(scrHandle); // 乗算済みアルファ用のアルファブレンドモードで描画 SetDrawBlendMode(DX_BLENDMODE_PMA_ALPHA, 255); DrawGraph(0, 0, spriteHandle, true); // 乗算済みアルファの画像を通常の画像に変換 int tempHandle = MakeScreen(xSize, ySize, TRUE); GraphFilterBlt( scrHandle, tempHandle, DX_GRAPH_FILTER_INTERP_ALPHA ); SetDrawScreen(tempHandle); sImgHandle = MakeARGB8ColorSoftImage(xSize, ySize); FillSoftImage(sImgHandle, 255, 255, 255, 0); GetDrawScreenSoftImage(0, 0, xSize - 1, ySize - 1, sImgHandle); if (filePath == NULL){ sprintfDx(defaultFilePath, "datas/test/%d.png", spriteHandle); SaveSoftImageToPng(defaultFilePath, sImgHandle, 0); } else{ SaveSoftImageToPng(filePath, sImgHandle, 0); } SetDrawScreen(DX_SCREEN_BACK); SetDrawBlendMode(DX_BLENDMODE_ALPHA, 255); DrawBox(0, 0, 399, 600, GetColor(0, 0, 0), true); DrawSoftImage(20, 20, sImgHandle); DrawBox(400, 0, 799, 600, GetColor(255, 255, 255), true); DrawSoftImage(420, 20, sImgHandle); DrawString(10, 10, "Software Image", GetColor(255, 255, 255)); ScreenFlip(); WaitKey(); DeleteSoftImage(sImgHandle); DeleteGraph(scrHandle); } void spriteExportTest(){ int Handle; // 乗算済みアルファの画像に変換して読み込む設定を ON にする SetUsePremulAlphaConvertLoad( TRUE ) ; Handle = LoadGraph("datas/test/1_original.png"); SetDrawScreen(DX_SCREEN_BACK); // 乗算済みアルファの画像用のアルファブレンドモードで描画 SetDrawBlendMode(DX_BLENDMODE_PMA_ALPHA, 255); DrawBox(0, 0, 399, 600, GetColor(0, 0, 0), true); DrawGraph(20, 20, Handle, true); DrawBox(400, 0, 799, 600, GetColor(255, 255, 255), true); DrawGraph(420, 20, Handle, true); DrawString(10, 10, "DrawGraph", GetColor(255, 255, 255)); ScreenFlip(); WaitKey(); ExportSingleSprite(Handle, "datas/test/1_exported.png"); DeleteGraph(Handle); Handle = LoadGraph("datas/test/2_original.png"); SetDrawScreen(DX_SCREEN_BACK); DrawBox(0, 0, 399, 600, GetColor(0, 0, 0), true); // 乗算済みアルファの画像用のアルファブレンドモードで描画 SetDrawBlendMode(DX_BLENDMODE_PMA_ALPHA, 255); DrawGraph(20, 20, Handle, true); DrawBox(400, 0, 799, 600, GetColor(255, 255, 255), true); DrawGraph(420, 20, Handle, true); DrawString(10, 10, "DrawGraph", GetColor(255, 255, 255)); ScreenFlip(); WaitKey(); ExportSingleSprite(Handle, "datas/test/2_exported.png"); DeleteGraph(Handle); } MakeScreen で作成できるアルファチャンネル付きの画像に対して半透明の描画を行った場合、 通常のアルファブレンドの描画では直感的に『多分こうなる』と思える描画結果になりませんので、 『乗算済みアルファ』というものを使って直感的な描画結果を得るようにする必要があります 『乗算済みアルファ』についてはこちらに解説がありますので、よろしければご覧ください m(_ _)m < 乗算済みアルファのすすめ > http://homepage2.nifty.com/natupaji/DxLib/lecture/PremulAlpha/PremulAlpha.html 上記ページを読んで頂けた前提でご説明しますと、まずアルファチャンネル付き画像( scrHandle )に 対して乗算済みアルファ用のアルファブレンドモードを使用して描画を行う為に、spriteExportTest で LoadGraph を使用して画像を読み込む前に SetUsePremulAlphaConvertLoad( TRUE ) ; を 実行して乗算済みアルファの画像に変換して読み込んでいます 次に ExportSingleSprite でアルファチャンネル付きの画像( scrHandle )に対して 『乗算済みアルファ用のアルファブレンドモード』で『乗算済みアルファの画像』を描画します そしてこれをそのまま保存してしまうと保存されるファイルは『乗算済みアルファの画像』と なってしまうので、GraphFilterBlt( DX_GRAPH_FILTER_INTERP_ALPHA ) を使用して 通常のアルファチャンネルつきの画像に変換しています
メンテ
Re: GetDrawScreenSoftImage について ( No.2 )
名前:tripper (解決) 日時:2016/02/21 15:47

ご返信ありがとうございます アルファチャンネル付き MakeScreen の使用者向けに 解決策が既に用意・掲載されていたようで大変失礼致しました 見落としておりました... 乗算済みαを用いることで正しい結果を得ることができました 懇切丁寧な対応をしていただき、ありがとうございました
メンテ

Page: 1 |

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

   クッキー保存