4

我在 onDraw() 中有这段代码。

radius = drawGmpImage(this.gmpImage, canvas);
canvas.drawCircle(kHorizontalOffset, kScreenVerticalOffset, radius , maskPaint);

drawGmpImage 创建一个复杂的图形,它是一个带有许多线条的圆圈。这是我无法更改的库函数。这些线是多边形,可以延伸到圆的圆周之外。

需要将画在圆圈外的所有内容“删除”。

这是来自 iOS 的一个端口,最初的开发人员解决方案是使用一个简单的位图掩码,存储为资源,并带有一个与绘制的圆圈大小相匹配的透明圆圈。只需在绘制的圆圈上绘制位图即可获得所需的效果,但在 Android 上不是一个选项,因为我需要支持所有可能的分辨率和比率。

因此,canvas.drawCircle() 调用是我尝试掩盖圆圈外所有内容的开始。它工作得很好,因为在我绘制的圆圈上绘制了一个实心圆圈,所以唯一剩下的就是绘制的圆圈圆周之外的多边形线。半径是绘制圆的半径。

我怎样才能把它倒过来,这样我就剩下圆圈的内容了?

4

2 回答 2

7

为什么你可以花几个小时做某事,放弃,提出问题,然后在 20 分钟后偶然发现答案?生活的乐趣。

Path path = new Path();
path.addCircle(kHorizontalOffset, kScreenVerticalOffset, radius, Path.Direction.CW);
canvas.clipPath(path);

我错过了 clipPath 方法,该方法将采用任何路径并将其用作剪切区域。将我的遮罩圈添加到路径中正是我所需要的。

[编辑]

这很好用,但是有一个问题。如果打开硬件加速,它就不起作用。我可以关闭加速,但随后在复杂的平局的其余部分中我失去了很多性能。

这是我最终解决的方法:

onSizeChanged()中,创建位图蒙版。我使用这种颜料在位图的正确位置绘制了一个透明圆圈。的关键是使用PorterDuffXfermode.

 maskPaint = new Paint();
 maskPaint.setColor(Color.TRANSPARENT);
 maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
 maskPaint.setStyle(Paint.Style.FILL);

然后创建位图

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {

    super.onSizeChanged(w, h, oldw, oldh);

    createMask(w,h,this.radius);

}

private void createMask(int w,int h, int radius){

    if (mask!=null){mask.recycle();}

    mask = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    Canvas maskCanvas = new Canvas(mask);
    maskCanvas.drawCircle(w, h, radius, maskPaint);

}

然后在 onDraw() 中,我只是在整个视图上绘制蒙版:

@Override
protected void onDraw(Canvas canvas){

    // draw the image();
    setRadius(drawGmpImage(this.gmpImage, canvas));
    canvas.drawCircle(kHorizontalOffset, kScreenVerticalOffset, radius , maskPaint);

    // overlay the mask bitmap
    if (mask != null) {
        canvas.drawBitmap(mask, 0f, 0f, bitmapPaint);
    }

如果半径发生变化,则重新创建蒙版:

 private void setRadius(int radius){

     this.radius = radius;
     createMask(kHorizontalOffset, kScreenVerticalOffset, radius);

 }
于 2013-01-28T23:02:30.233 回答
1

我不知道如何使用面具来实现这一点,因此另一种方法:

你可以用特定的颜色绘制半径,比如黑色。

比来自角落之一的洪水填埋场。在它不是很困难之前,我已经创建了一个 Floodfill 算法。您从左上角开始,将该像素设置为您想要的颜色。然后你看看相邻的像素。如果它们是黑色的,你就停在那个方向,如果不是,你改变颜色并再次查看相邻的像素。

祝你好运

于 2013-01-28T22:21:15.033 回答