モブ沢工房

プログラミングとかLinux関連(特にOSSのグラフィックツール関連)とかレトロゲームとか3Dプリンタやら日曜大工等、色々。

フルカラーアルファ付きpng画像とAzDrawing:前言撤回編

もうgimpとか関係ないのでタイトルは変わりましたw

それにしても、また前言撤回か!

と自分でも思いますが、昨日布団の中に入ってじっくり考えていて うむぅ…?と思ったのです。

昨日の記事はよく考えるとおかしい。

アルファ値をピクセルにコンポジットしたほうがいいのではないだろうか??

と思ってやってみますた。

まず、inkscapeにて以下のようなpngを作成。 3つ星があって、真ん中の星が最下層にあり、白黒グラデで一見わかりづらいですが、実は星の全域が不透明です。 その他の星は薄いグラデの半透明になっています。

f:id:dothiko:20141203135037p:plain

これをAzDrawing 1.4にそのまま読み込むと…

f:id:dothiko:20141203135123j:plain

となります。

しかし、こうではないだろうか?

f:id:dothiko:20141203135207j:plain

つまり不透明部分の模様は濃度として反映されるべきではないだろうか?という考え方です。

ちなみに、これの下にレイヤを作って濃度半分のブラシでベジェを描いた場合はこんなふうです。

f:id:dothiko:20141203135215j:plain

うーむ。

この方法だと当たり前ながら、必然的に本来不透明な部分の下が見えてしまう、これはどうか…?とも思いますが…

この下に白いレイヤを作るなり、描線を一部消去するだけで状況を再現できることを考えれば、こっちのほうがいいんではないかと…

おっと、普通に24ビットに変換したのを読むのとはどう違うのか?違わない気がする。一応やってみました。

f:id:dothiko:20141203224500j:plain

ていうかアレですね。スクリーンキャプチャした画像でgimp上で「差の絶対値」で比較したら真っ黒になったので、単にアルファ値を無視して読み込むのと全く同じということですねw

だとすればやはりアルファ値を特別に扱う現行の方法のほうが、余程意味があるような気が…

ま、まぁともかく、無意味な話なのですが一応、コードは以下のように改変しました。src/img/CTileImg.cppの

void CTileImg::convFrom32Bit(const CImage32 &src,int sx,int sy,BOOL bAlpha)

のループ部分を、

    int curpixel;

    for(iy = h; iy > 0; iy--, pd += 64 - w, ps += sw - w)
    {
        for(ix = w; ix > 0; ix--, pd++, ps++)
        {
            curpixel = 255 - ((ps->r * 77 + ps->g * 150 + ps->b * 29) >> 8);
            if(bAlpha)
            {
                *pd=(BYTE)((((int)ps->a * curpixel) >> 8));
            }
            else
            {
                *pd=(BYTE)curpixel;
            }
         }
    }

というようにです。

いろいろ考えた結果、

  • オプションで設定する
  • ファイルダイアログでアルファ値を無視することを明示的に選択する

ような機能があれば問題ないな〜とか思いました。 うーむ、初sourceforge、行ってみるか…?