PorterDuffXfermode DST_IN无法按预期工作

时间:2012-11-30 22:50:13

标签: java android drawing masking porter-duff

所以我试图加快我们正在做的一些绘图(用alpha透明度绘制弧的一部分)并尝试将整个弧缓存到单独的位图中,并选择性地使用alpha蒙版显示它。

根据我已完成的研究(适用于Android的Xfermodes API演示,this examplethis tool),如果我有以下两个图形:

enter image description here

enter image description here

并使用以下内容绘制:

Xfermode DST_IN = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

canvas.drawBitmap(circle, 0, 0, paint);
paint.setXfermode(DST_IN);
canvas.drawBitmap(arc, 0, 0, paint);
paint.setXfermode(null);

我应该得到这个结果:

enter image description here

将目标图像(圆圈)剪切到绘制源图像(圆弧)的区域。相反,我得到了完整的圆圈。如果我只是绘制弧线,它会出现在正确的位置,如果我使用DST_OUT,我得到预期结果的倒数(圆圈的其他三个象限)。

我还确保为此视图禁用硬件渲染,以防此Xfermode出现问题,但它没有任何区别。

我把它分解成一个最简单的单独项目试图让它工作,并使用下面的代码,我仍然有同样的问题:

public class ClippedView extends View {
    private Xfermode DST_IN, DST_OUT;
    private Paint paint;

    public ClippedView(Context context) {
        super(context);
        init();
    }

    private void init() {
        setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        this.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        DST_IN = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
        DST_OUT = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        paint.setColor(Color.GREEN);
        canvas.drawRect(0, 0, getWidth() / 2, getHeight() / 2, paint);
        paint.setColor(Color.BLACK);
        paint.setXfermode(DST_IN);
        canvas.drawCircle(getWidth() / 2, getHeight() / 2, getWidth() / 2, paint);
        paint.setXfermode(null);
    }
}

我使用它错了吗?我只是错过了一些东西吗?我发现了一个错误吗? :)

1 个答案:

答案 0 :(得分:5)

有一种更便宜,更简单的方法来实现这一目标:使用剪辑。 Canvas.clipRect()就足够了。你的解决方案正在燃烧很多填充物。您可以使用SRC_IN而不是DST_IN来获得所需的效果。但要小心:它只能在透明的Bitmap或图层中使用。当您直接在屏幕上绘制时,目标已被窗口背景填充。