如何擦除 Android 画布中的一个自定义区域(使其透明)?

发布于 2025-01-06 01:18:16 字数 1079 浏览 0 评论 0原文

我正在覆盖 Android 的 ImageView 以使图像的角透明。我可以在 onDraw(Canvas canvas) 中完成裁剪画布:

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

不幸的是,不可能对这个圆角矩形进行抗锯齿,结果是丑陋的角落,如下所示:

在此处输入图像描述

我知道我可以使用 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);
}

有没有什么方法可以“擦除”不是圆角矩形,而是相反的,即圆角?如果我只想擦除其中一个角怎么办?

I'm overriding Android's ImageView in order to make the corners of my image transparent. I can accomplish that clipping the canvas in my onDraw(Canvas canvas):

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

Unfortunately, it's not possible to antialias this round rectangle, and the result are ugly corners like this:

enter image description here

I know I can clear parts of my canvas with antialiasing using Paint and PorterDuff.Mode.CLEAR, what I don't know is to specify the round corners as the region to be erased. I'm looking for something like this:

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

Is there any way to "erase" not the round rectangle, but it's inverse, ie, the round corners? And what if I just want to erase one of the corners?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

节枝 2025-01-13 01:18:16

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

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

}

Draw using a BitmapShader with a transparent color for your Paint object.
If you just want to erase one of the corners, try drawing it as a Path instead of a 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);

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文