5

2つの画像をマージする必要がある画像編集ツールに取り組んでいます。gimpのようなほとんどの画像編集ツールは、画像のマージまたはブレンドにPorterDuffモードを使用します。私もアンドロイドで同じアプローチを使用しています。
androidが提供するPorterDuffモードの数が限られているため、目的の結果を得ることができません。そこで、Androidに含まれていないPorterDuffモード(オーバーラップ、ハードライト、ソフトライト、カラーバーン、カラーダッジ)の実装を考えています。
問題は、どこから始めればよいかわからないことです。したがって、この点に関する参考資料やガイダンスは高く評価されます。

4

1 に答える 1

3

これは、AndroidでオーバーレイPorterDuffモードを実装する方法です。

public class MyPorterDuffMode
{

    public Bitmap applyOverlayMode(Bitmap srcBmp, Bitmap destBmp)
    {
        int width = srcBmp.getWidth();
        int height = srcBmp.getHeight();
        int srcPixels[] = new int[width * height];;
        int destPixels[] = new int[width * height];
        int resultPixels[] = new int[width * height];
        int aS = 0, rS = 0, gS = 0, bS = 0;
        int rgbS = 0;
        int aD = 0, rD = 0, gD = 0, bD = 0;
        int rgbD = 0;

        try
        {
            srcBmp.getPixels(srcPixels, 0, width, 0, 0, width, height);
            destBmp.getPixels(destPixels, 0, width, 0, 0, width, height);
            srcBmp.recycle();
            destBmp.recycle();
        }
        catch(IllegalArgumentException e)
        {
        }
        catch(ArrayIndexOutOfBoundsException e)
        {
        }

        for(int y = 0; y < height; y++)
        {
            for(int x = 0; x < width; x++)
            {
                rgbS = srcPixels[y*width + x];
                aS = (rgbS >> 24) & 0xff;
                rS = (rgbS >> 16) & 0xff;
                gS = (rgbS >>  8) & 0xff;
                bS = (rgbS      ) & 0xff;

                rgbD = destPixels[y*width + x];
                aD = ((rgbD >> 24) & 0xff);
                rD = (rgbD >> 16) & 0xff;
                gD = (rgbD >>  8) & 0xff;
                bD = (rgbD      )  & 0xff;

                //overlay-mode
                rS = overlay_byte(rD, rS, aS, aD);
                gS = overlay_byte(gD, gS, aS, aD);
                bS = overlay_byte(bD, bS, aS, aD);
                aS = aS + aD - Math.round((aS * aD)/255f);

                resultPixels[y*width + x] = ((int)aS << 24) | ((int)rS << 16) | ((int)gS << 8) | (int)bS;
            }
        }

        return Bitmap.createBitmap(resultPixels, width, height, srcBmp.getConfig());
    }



    // kOverlay_Mode
    int overlay_byte(int sc, int dc, int sa, int da) {
        int tmp = sc * (255 - da) + dc * (255 - sa);
        int rc;
        if (2 * dc <= da) {
            rc = 2 * sc * dc;
        } else {
            rc = sa * da - 2 * (da - dc) * (sa - sc);
        }
        return clamp_div255round(rc + tmp);
    }


    int clamp_div255round(int prod) {
        if (prod <= 0) {
            return 0;
        } else if (prod >= 255*255) {
            return 255;
        } else {
            return Math.round((float)prod/255);
        }
    }

}

注:ビットマップを抽出するときに、構成をARGB_8888に設定します。これは重要です。
画像のブレンドやカラー操作を行う場合は、RGB_565モードではなく、ARGB_8888モードになっていることを確認する必要があります。2.3までは、メモリを節約するために明示的に指示しない限り、Androidは通常デフォルトでRGB_565モードになります。

BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Config.ARGB_8888;
于 2012-11-06T11:02:31.247 に答える