我正在尝试加速我们正在进行的绘图过程(使用 alpha 透明度绘制弧线的一部分),并尝试将整个弧线缓存到一个单独的位图中,并使用 alpha 蒙版进行选择性显示。根据我所做的研究(Android 的 Xfermodes API 演示、this example 和 this tool),如果我有以下两个图形:
并使用以下内容进行绘制:
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);
我应该得到这个结果:
目标图像(圆)被裁剪到绘制源图像(弧)的区域。然而,我得到了完整的圆形。如果只绘制弧,它会出现在正确的位置,如果使用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);
}
}
我使用方法不正确吗?是我遗漏了什么吗?还是我发现了一个bug?:)