1

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

任何人都知道如何做这样的事情?这是我的(简化的)尝试:

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

这是我得到的图像:

在此处输入图像描述

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

4

1 回答 1

0

事实证明,诀窍是添加另一层。

    // 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,你可能是对的。使用PathandarcTo()将是一个更好的解决方案。我避免这种方法的唯一原因是 b/carcTo()是 api 21+ 功能。到目前为止,我已经设法将 api 保持在 17+。但是,如果其他人想提供一个arcTo()比较酷的完整性解决方案。

于 2016-08-09T02:32:00.087 回答