Canvas.clipPath(Path) 未按预期剪切

Posted

技术标签:

【中文标题】Canvas.clipPath(Path) 未按预期剪切【英文标题】:Canvas.clipPath(Path) not clipping as expected 【发布时间】:2012-11-20 07:14:58 【问题描述】:

我正在尝试将画布绘图操作剪辑为弧形楔形。但是,在将剪切路径设置为画布后,我没有得到预期的结果。

为了说明,这是我正在做的事情:

path.reset();

//Move to point #1
path.moveTo(rect.centerX(), rect.centerY());

//Per the documentation, this will draw a connecting line from the current
//position to the starting position of the arc (at 0 degrees), add the arc
//and my current position now lies at #2.
path.arcTo(rect, 0, -30);

//This should then close the path, finishing back at the center point (#3)
path.close();

这可行,当我简单地绘制这条路径 (canvas.drawPath(path, paint)) 时,它会绘制如上所示的楔形。但是,当我将此路径设置为画布的剪切路径并绘制到其中时:

//I've tried it with and without the Region.Op parameter
canvas.clipPath(path, Region.Op.REPLACE);
canvas.drawColor(Color.BLUE);

我得到以下结果(留下楔形只是为了显示参考):

因此,它似乎剪裁到Path 的边界矩形,而不是Path 本身。有什么想法吗?

编辑 作为更新,我发现了一种更有效的方法,它允许硬件加速。首先,将整个图像(您将要剪裁的)绘制到屏幕外位图中。使用此Bitmap 制作BitmapShader,将该着色器设置为Paint,然后使用该Paint 对象绘制楔形路径:

drawMyBitmap(bitmap);
Shader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setShader(shader);

@Override
public void onDraw(Canvas canvas) 
    canvas.drawArc(rect,         //The rectangle bounding the circle
                   startAngle,   //The angle (CW from 3 o'clock) to start
                   sweepAngle,   //The angle (CW from 3 o'clock) of the arc
                   true,         //Boolean of whether to draw a filled arc (wedge)
                   paint         //The paint with the shader attached
    );

【问题讨论】:

您使用的是HC或更高版本还是使用硬件加速? developer.android.com/guide/topics/graphics/hardware-accel.html。如果是这样,clipPath 不受支持且存在问题。 @Simon:天哪。呵呵。遗憾的是,这周我经常提到该文件,但我完全忽略了这一点。禁用 HW Accel 效果很好!如果您将此作为答案发布,我会接受。你是救生员! 很高兴能帮上忙。祝你好运。 美丽的问题! 你究竟是如何做到这一点的?:“首先,将整个图像(你将要剪裁的)绘制到屏幕外位图中” 【参考方案1】:

您是使用 HC 或更高版本还是使用硬件加速?

如果是这样,clipPath 不受支持且存在问题。

developer.android.com/guide/topics/graphics/hardware-accel.html.

【讨论】:

这就是问题所在。 :) 将绘图操作的剪切部分移动到屏幕外位图中,然后将其绘制回硬件加速画布,它就像一个魅力!再次感谢! @kcoppock 这听起来有点倒退。为什么不直接将视图的图层类型转换为软件,仍然在onDraw() 中进行绘图? @RichardJ.RossIII 那会更有意义。 :) 当时我对此有点陌生。我已经用我现在处理这个问题的新方式进行了编辑,不过感谢您的输入!【参考方案2】:

OP 的问题是关于使用剪辑区域的,@Simon 已经回答了。但是请记住,还有一种更直接的方式来绘制实心圆弧:

创建Paint

mPaint = new Paint();
mPaint.setColor(Color.BLUE);
mPaint.setStyle(Style.FILL);
mPaint.setAntiAlias(true);

绘制的时候,简单的画路径:

canvas.drawPath(path, mPaint);

【讨论】:

以上是关于Canvas.clipPath(Path) 未按预期剪切的主要内容,如果未能解决你的问题,请参考以下文章

Android画圆形图片,clippath方式/Xfermode方式

canvas.clipPath() 在少数设备上不起作用

MySQL 索引未按预期使用

Android clipPath导致卡顿

Test-Path / System.IO.Directory::Exists 未按预期工作

枕头图像打开保存未按预期工作[重复]