【问题标题】:Transparency made from interstection交汇处的透明度
【发布时间】:2016-08-08 14:43:02
【问题描述】:

把我的耳朵拉出来。我有一个背景位图,我想在上面覆盖另一个位图,上面有透明的切口。如果切口是基本形状,我这样做没有问题,但我需要切口是两个圆的交点(有点像叶子形状)。我尝试制作第三个位图来生成剪切模板,但我什至无法获得剪切的清晰表示,更不用说让它作为剪切模板工作了。

有人知道怎么做这样的事情吗?这是我的(简化的)尝试:

@Override
public void draw(Canvas canvas) {
    float w = canvas.getWidth();
    float h = canvas.getHeight();

    // just used to set some proportions
    float off = 300f;

    Paint paint = new Paint();

    // make a background bitmap with a yellow to green gradient
    Bitmap bitmapBkg = Bitmap.createBitmap((int) w, (int) h, Bitmap.Config.ARGB_8888);
    Canvas canvasBkg = new Canvas(bitmapBkg);
    paint.reset();
    paint.setShader(new LinearGradient(0, h/2 - off, 0, h/2 + off, Color.YELLOW, Color.GREEN, Shader.TileMode.CLAMP));
    canvasBkg.drawRect(new RectF(0, 0, w, h), paint);

    // make an overlay bitmap with a red to magenta gradient which will have the cutouts
    Bitmap bitmapOver = Bitmap.createBitmap((int) w, (int) h, Bitmap.Config.ARGB_8888);
    Canvas canvasOver = new Canvas(bitmapOver);
    paint.reset();
    paint.setShader(new LinearGradient(0, h/2 - off, 0, h/2 + off, Color.RED, Color.MAGENTA, Shader.TileMode.CLAMP));
    canvasOver.drawRect(new RectF(0, 0, w, h), paint);

    // make a bitmap of intersecting circles to be used as the cutout shape
    Bitmap bitmapCut = Bitmap.createBitmap((int) w, (int) h, Bitmap.Config.ARGB_8888);
    Canvas canvasCut = new Canvas(bitmapCut);

    paint.reset();
    paint.setColor(Color.BLACK);
    //paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XOR));
    canvasCut.drawCircle(w / 2 - (off / 2 ), h / 2, off, paint);

    paint.reset();
    paint.setColor(Color.BLACK);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XOR));
    canvasCut.drawCircle(w / 2 + (off / 2), h / 2, off, paint);

    // apply cutout to overlay
    paint.reset();
    paint.setColor(Color.BLACK);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP));
    canvasOver.drawBitmap(bitmapCut, 0, 0, paint);

    // draw background and overlay onto main canvas
    paint.reset();
    paint.setColor(Color.BLACK);
    canvas.drawBitmap(bitmapBkg, 0, 0, paint);
    canvas.drawBitmap(bitmapOver, 0, 0, paint);
}

这是我得到的图像:

我想要得到的外部部分也是红色洋红色;只有中间的眼睛是黄绿色的。

【问题讨论】:

  • 也许可以利用 PorterDuff 组合图像? stackoverflow.com/questions/8280027/…
  • 这就是我一直在尝试使用的。
  • 出了什么问题?
  • 上面的代码显示了我所能得到的最接近的。我得到了一个切口,但其余的背景应该是红色洋红色的覆盖层——我只得到了圆圈。
  • 你能张贴一张你想要什么和你得到什么的照片吗?

标签: android canvas bitmap porter-duff


【解决方案1】:

原来诀窍是再添加一层。

    // make a secondary overlay that cuts out the whole circles
    Bitmap bitmapOver2 = Bitmap.createBitmap((int) w, (int) h, Bitmap.Config.ARGB_8888);
    Canvas canvasOver2 = new Canvas(bitmapOver2);
    paint.reset();
    paint.setShader(new LinearGradient(0, h / 2 - off, 0, h / 2 + off, Color.RED, Color.MAGENTA, Shader.TileMode.CLAMP));
    canvasOver2.drawRect(new RectF(0, 0, w, h), paint);
    paint.reset();
    paint.setColor(Color.BLACK);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
    canvasOver2.drawCircle(w / 2 - (off / 2), h / 2, off, paint);
    canvasOver2.drawCircle(w / 2 + (off / 2), h / 2, off, paint);

像这样应用它:

    // draw background and overlay onto main canvas
    paint.reset();
    paint.setColor(Color.BLACK);
    canvas.drawBitmap(bitmapBkg, 0, 0, paint);
    canvas.drawBitmap(bitmapOver2, 0, 0, paint);
    canvas.drawBitmap(bitmapOver, 0, 0, paint);

基本上这是一个小把戏。它绘制了中间层背景两次,一次带有完整的圆形切口,另一次带有眼睛形状的切口。两者配合得恰到好处,可以达到预期的效果。

当然@Rotwang,你可能是对的。使用PatharcTo() 将是一个更好的解决方案。我避免这种方法的唯一原因是 b/c arcTo() 是 api 21+ 功能。到目前为止,我已经设法将 api 保持在 17+。但是,如果其他人想提供一个 arcTo() 的完整性解决方案,那将是很酷的比较。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-05
    • 2020-07-12
    • 1970-01-01
    • 1970-01-01
    • 2017-01-11
    • 2021-11-01
    • 2013-06-05
    相关资源
    最近更新 更多