トップページ > 記事閲覧
SaveDrawScreenToPNG関数について
名前:na 日時: 2017/04/07 23:38

画像を保存すると,アルファチャンネルが追加されて透明になってしまうところができてしまいます。 ポーカーで使うコインみたいのをつくろうとしていたら,周りの六個の四角が透過されてしまいました。 http://or2.mobi/index.php?mode=image&file=152646.png 画像自体はビットマップで保存して後でpng形式にすればいいのですが,,, なぜ,一部分だけ透明になってしまうのですか。 以下,ソースコードです。 #include <cmath> #include "dxlib.h" int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { if (DxLib_Init() == -1 || ProcessMessage() == -1) goto __END; const auto x = 101; const auto y = 101; const auto r1 = 100; const auto r2 = 70; const auto en = 1; const auto nu = 2; const auto be = 16 * Pi * nu / 180; DrawCircleAA(x, y, r1 * en, 100, GetColor(0xff, 0xff, 0xff), 1); for (auto i = 7 * Pi * nu / 180; i < 2 * Pi; i += 30 * Pi * nu / 180) { auto cos_i = cos(i); auto cos_be = cos(i + be); auto sin_i = sin(i); auto sin_be = sin(i + be); for (auto j = 0.; j < be; j += .01) { DrawTriangleAA ( r2 * cos_i * en + x, r2 * sin_i * en + y, r1 * cos_i * en + x, r1 * sin_i * en + y, r1 * cos(i + j) * en + x, r1 * sin(i + j) * en + y, GetColor(0xcc, 0xcc, 0xcc), false ); DrawTriangleAA ( r1 * cos_i * en + x, r1 * sin_i * en + y, r1 * cos_be * en + x, r1 * sin_be * en + y, r2 * cos(i + j) * en + x, r2 * sin(i + j) * en + y, GetColor(0xcc, 0xcc, 0xcc), false ); } } DrawCircleAA(x, y, r2 * en, 100, GetColor(0xff, 0xff, 0xff), true); DrawCircleAA(x, y, 0.8 * r2 * en, 100, GetColor(0xcc, 0xcc, 0xcc), true); DrawCircleAA(x, y, r1 * en, 100, GetColor(0x00, 0x00, 0x00), false); DrawCircleAA(x, y, r1 * en + 1, 100, GetColor(0x00, 0x00, 0x00), false); DrawCircleAA(x, y, r2 * en, 100, GetColor(0x00, 0x00, 0x00), false); DrawCircleAA(x, y, r2 * en - 1, 100, GetColor(0x00, 0x00, 0x00), false); SaveDrawScreenToPNG(0, y - 101, 202 * 4, y + 101, "save.png"); WaitKey(); __END: DxLib_End(); return 0; }
メンテ

Page: 1 |

Re: SaveDrawScreenToPNG関数について ( No.1 )
名前:管理人 日時:2017/04/08 15:58

DirectX11 を使用する環境では裏画面はアルファチャンネル付きの画像となっているのですが、 アルファチャンネル付きの画像に対して半透明のものを通常のアルファブレンドで描画すると計算上意図した結果が得られません ( アンチエイリアス付きの図形描画は、アンチエイリアスが掛かっている縁の部分は半透明の描画となっています ) なので、意図した描画結果を得るためには『乗算済みアルファ』というものを使用する必要があります なぜ通常の描画では意図した結果が得られないのかや、『乗算済みアルファ』とは何かについて こちらの『乗算済みアルファのすすめ』に解説がありますので、よろしければご覧ください m(_ _)m <乗算済みアルファのすすめ> https://dxlib.xsrv.jp/lecture/PremulAlpha/PremulAlpha.html そして載せていただいたプログラムを『乗算済みアルファ』を使用して意図通りのpng画像が保存できるように 変更してみましたので、よろしければ参考にしてください m(_ _)m #include <cmath> #include "dxlib.h" int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { ChangeWindowMode( TRUE ) ; SetGraphMode( 808, 202, 32 ) ; // 結果が分かりやすいように背景色を黒以外に変更 SetBackgroundColor( 128,128,0 ) ; if (DxLib_Init() == -1 || ProcessMessage() == -1) goto __END; // 保存画像と同サイズのアルファチャンネルつき仮画面を作成 int TempScreen = MakeScreen( 808, 202, TRUE ) ; // 描画先を仮画面に変更 SetDrawScreen( TempScreen ) ; // ブレンドモードを乗算済みアルファ用のモードに変更 SetDrawBlendMode( DX_BLENDMODE_PMA_ALPHA, 255 ) ; const auto x = 101; const auto y = 101; const auto r1 = 100; const auto r2 = 70; const auto en = 1; const auto nu = 2; const auto be = 16 * DX_PI * nu / 180; DrawCircleAA(x, y, r1 * en, 100, GetColor(0xff, 0xff, 0xff), 1); for (auto i = 7 * DX_PI * nu / 180; i < 2 * DX_PI; i += 30 * DX_PI * nu / 180) { auto cos_i = cos(i); auto cos_be = cos(i + be); auto sin_i = sin(i); auto sin_be = sin(i + be); for (auto j = 0.; j < be; j += .01) { DrawTriangleAA ( r2 * cos_i * en + x, r2 * sin_i * en + y, r1 * cos_i * en + x, r1 * sin_i * en + y, r1 * cos(i + j) * en + x, r1 * sin(i + j) * en + y, GetColor(0xcc, 0xcc, 0xcc), false ); DrawTriangleAA ( r1 * cos_i * en + x, r1 * sin_i * en + y, r1 * cos_be * en + x, r1 * sin_be * en + y, r2 * cos(i + j) * en + x, r2 * sin(i + j) * en + y, GetColor(0xcc, 0xcc, 0xcc), false ); } } DrawCircleAA(x, y, r2 * en, 100, GetColor(0xff, 0xff, 0xff), true); DrawCircleAA(x, y, 0.8 * r2 * en, 100, GetColor(0xcc, 0xcc, 0xcc), true); DrawCircleAA(x, y, r1 * en, 100, GetColor(0x00, 0x00, 0x00), false); DrawCircleAA(x, y, r1 * en + 1, 100, GetColor(0x00, 0x00, 0x00), false); DrawCircleAA(x, y, r2 * en, 100, GetColor(0x00, 0x00, 0x00), false); DrawCircleAA(x, y, r2 * en - 1, 100, GetColor(0x00, 0x00, 0x00), false); // 仮画面の画像を乗算済みアルファの画像から通常の画像に変換 GraphFilter( TempScreen, DX_GRAPH_FILTER_INTERP_ALPHA ) ; SaveDrawScreenToPNG(0, y - 101, 202 * 4, y + 101, "save.png"); // 描画先を表画面に変更 SetDrawScreen( DX_SCREEN_FRONT ) ; // 仮画面の内容を描画 DrawGraph( 0, 0, TempScreen, TRUE ) ; WaitKey(); __END: DxLib_End(); return 0; }
メンテ
Re: SaveDrawScreenToPNG関数について ( No.2 )
名前:na 日時:2017/04/08 20:16

返信ありがとうございます。 理由をわかりやすく教えていただき,助かりました。
メンテ

Page: 1 |

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

   クッキー保存