Android PorterDuff.Mode.DST_IN与Bitmap.Config.ALPHA_8组合

Ark*_*mza 6 android bitmap porter-duff android-canvas

我在玩位图遮罩,尝试ALPHA_8PorterDuff.Mode.DST_INPaint 绘制位图遮罩时偶尔发现一个有趣的问题。至少在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);
    }
...
Run Code Online (Sandbox Code Playgroud)

mMaskBitmapARGB_8888配置时,它可以正常工作。但是,当我使用ALPHA_8它时,它不会。在这种情况下,图片完全不会被掩盖。

这是我在活动中加载资源的方式:

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

请注意,.extractAlpha()这给了我ALPHA_8位图。

这是我使用Drawable的方法:

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

更有趣的是,当我尝试另一种方法时,先绘制蒙版,然后使用SRC_INPaint 绘制图片-即使使用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);
    }
Run Code Online (Sandbox Code Playgroud)

...

这是我在GitHub上尝试过的整个项目的链接。它包含非工作和工作解决方案,请随时使用。

任何人都知道为什么DST_IN和组合ALPHA_8不能按预期工作吗?