2012-12-02 108 views
16

我试图将画布绘制操作剪裁成弧形的楔形。但是,在将剪切路径设置为画布后,我没有得到预期的结果。Canvas.clipPath(路径)不按预期裁剪

为了说明,下面是我在做什么:

enter image description here

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); 

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

enter image description here

因此,它似乎将剪辑到Path的边界矩形,而不是Path本身。任何想法发生了什么?

编辑就像更新一样,我发现了一个更有效的方法来实现硬件加速。首先,将整个图像(您将要裁剪的)绘制到离屏位图中。做一个BitmapShader使用此Bitmap,该着色器设置为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 
    ); 
} 
+1

是否使用

一个Paint创建慧聪或以上或以其他方式使用硬件加速? http://developer.android.com/guide/topics/graphics/hardware-accel.html。如果是这样,clipPath不受支持并且存在问题。 – Simon

+1

@Simon:噢,天哪。嘿。不幸的是,本周我一直在提及这份文件,但我完全忽略了这一点。禁用硬件加速完美工作!如果您将此作为答案发布,我会接受它。你是一个救星! – kcoppock

+0

很高兴有帮助。祝你好运。 – Simon

回答

9

您是否使用HC或以上或以其它方式使用硬件加速?

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

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

+1

这就是问题所在。 :)将绘图操作的剪切部分移动到离屏位图上,然后将其绘制回硬件加速画布,并且它就像一个魅力!再次感谢! – kcoppock

+1

@kcoppock听起来有点倒退。你为什么不把视图的图层类型转换成软件,仍然在'onDraw()'中做绘图? –

+0

@ RichardJ.RossIII这样做会更有意义。:)当时我对此有点不熟悉。我已经以新的方式编辑了,现在我正在处理这个问题,感谢您的输入! – kcoppock

2

OP的问题是关于使用剪辑区域,并已由@Simon回答。请记住,但是,有画充满弧度的更直接的方式:

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

在绘制时,简单地画的路径:

canvas.drawPath(path, mPaint);