2012-02-14 1001 views
4

我重写Android的ImageView以使图像的角落透明。我能够做到这裁剪画布在我的onDraw(帆布油画):如何在Android画布中擦除(使透明)一个自定义区域?

@Override 
protected void onDraw(Canvas canvas) { 
    Path clipPath = new Path(); 
    int w = this.getWidth(); 
    int h = this.getHeight(); 
    clipPath.addRoundRect(new RectF(0,0,w,h), 10.0f, 10.0f, Path.Direction.CW); 
    canvas.clipPath(clipPath); 
    super.onDraw(canvas); 
} 

不幸的是,这是不可能的抗锯齿这个圆角矩形,其结果是丑陋的角落这样的:

enter image description here

我知道我可以使用PaintPorterDuff.Mode.CLEAR来清除我的画布部分的抗锯齿,我不知道的是将圆角指定为要擦除的区域。我在寻找这样的事情:

@Override 
protected void onDraw(Canvas canvas) { 
    //superclass will draw the bitmap accordingly 
    super.onDraw(canvas); 

    final Paint paint = new Paint(); 
    paint.setAntiAlias(true); 
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 

    //this will erase a round rectangle, I need the exact inverse 
    canvas.drawRoundRect(rect, rx, ry, paint); 
} 

有什么办法“抹掉”,而不是圆角矩形,但它的倒数,即,圆角?而如果我只想抹掉其中一个角落呢?

回答

4

使用带有透明颜色的BitmapShader绘制Paint对象。
如果您只想擦除其中一个角落,请尝试将其绘制为路径而不是RoundRect。

protected void onDraw(Canvas canvas) { 
    BitmapShader bitmapShader = new BitmapShader(<original drawable>, TileMode.CLAMP, TileMode.CLAMP); 

    Paint paint = new Paint(); 
    paint.setAntiAlias(true); 
    paint.setColor(0xFF000000); 
    paint.setShader(bitmapShader); 

    canvas.drawRoundRect(rect, rx, ry, paint); 

} 
+0

但是我应该在我的onDraw()中绘制实际的原始drawable吗?我在android源代码中看到[ImageView的onDraw()](http://androidxref.com/source/xref/frameworks/base/core/java/android/widget/ImageView.java)执行不同类型的检查和画布修改(例如:填充)。 – Pedro 2012-02-14 15:15:04

+0

您将原始绘图作为BitmapShader绘制。圆角矩形之外的区域将以透明方式绘制。 – Freddroid 2012-02-14 15:20:54

+0

“BitmapShader”的第一个参数不是可绘制的,而是位图。 – 2015-02-18 09:40:51