8

私はビットマップ マスキングをいじっていましたが、ペイントでALPHA_8ビットマップ マスクを描画しようとすると、時折興味深い問題が見つかりました。PorterDuff.Mode.DST_IN少なくとも Android 6.x および 5.x では機能しません。
これが私のドローアブルコードのサンプルです:

public class MaskedDrawablePorterDuffDstIn extends Drawable {

    private Bitmap mPictureBitmap;
    private Bitmap mMaskBitmap;
    private Bitmap mBufferBitmap;
    private Canvas mBufferCanvas;
    private final Paint mPaintDstIn = new Paint();

    public MaskedDrawablePorterDuffDstIn() {
        mPaintDstIn.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
    }

    @Override
    public void draw(Canvas canvas) {
        if (mPictureBitmap == null || mMaskBitmap == null) {
            return;
        }

        mBufferCanvas.drawBitmap(mPictureBitmap, 0, 0, null);
        mBufferCanvas.drawBitmap(mMaskBitmap, 0, 0, mPaintDstIn);
        canvas.drawBitmap(mBufferBitmap, 0, 0, null);
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        super.onBoundsChange(bounds);
        final int width = bounds.width();
        final int height = bounds.height();

        if (width <= 0 || height <= 0) {
            return;
        }

        mBufferBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        mBufferCanvas = new Canvas(mBufferBitmap);
    }
...

mMaskBitmap構成がある場合ARGB_8888、問題なく動作します。しかし、私が使用するときALPHA_8はそうではありません。その場合、画像はまったくマスクされません。

アクティビティにリソースをロードする方法は次のとおりです。

private void loadImages() {
    mPictureBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.picture);
    mMaskBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.mask_circle).extractAlpha();
}

.extractAlpha()私にビットマップを与えていることに注意してくださいALPHA_8

Drawable の使用方法は次のとおりです。

public void setDrawablePDDstIn(View view) {
    MaskedDrawablePorterDuffDstIn maskedDrawable = new MaskedDrawablePorterDuffDstIn();
    maskedDrawable.setPictureBitmap(mPictureBitmap);
    maskedDrawable.setMaskBitmap(mMaskBitmap);
    mImageView.setImageDrawable(maskedDrawable);
}

さらに興味深いのは、最初にマスクを描画してからSRC_INペイントで絵を描く別のアプローチを試すと、マスクを使用しても問題なく動作しますALPHA_8

public class MaskedDrawablePorterDuffSrcIn extends Drawable {

    private Bitmap mPictureBitmap;
    private Bitmap mMaskBitmap;
    private Bitmap mBufferBitmap;
    private Canvas mBufferCanvas;
    private final Paint mPaintSrcIn = new Paint();

    public MaskedDrawablePorterDuffSrcIn() {
        mPaintSrcIn.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    }
    @Override
    public void draw(Canvas canvas) {
        if (mPictureBitmap == null || mMaskBitmap == null) {
            return;
        }

        mBufferCanvas.drawBitmap(mMaskBitmap, 0, 0, null);
        mBufferCanvas.drawBitmap(mPictureBitmap, 0, 0, mPaintSrcIn);

        //dump the buffer
        canvas.drawBitmap(mBufferBitmap, 0, 0, null);
    }

...

これは、私がGitHubで実験したプロジェクト全体へのリンクです。動作しないソリューションと動作するソリューションの両方が含まれているので、自由に遊んでください。

と の組み合わせが期待どおりに機能しない理由を知っている人はいDST_INますALPHA_8か?

4

0 に答える 0