Canvas 在 drawable 中绘制颜色。不要触摸图像的透明部分

Canvas draw color inside drawable. Dont touch transparent part of image

我有一个左右两部分透明的可绘制对象。我需要在里面画一些进步。

startDrawable.setBounds(0, 0, startDrawable.getIntrinsicWidth(), canvas.getHeight());
            startDrawable.draw(canvas);
            Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
            paint.setColor(Color.BLACK);
            Path path = new Path();
            path.moveTo(0, 0);
            path.lineTo(startDrawable.getIntrinsicWidth() / 2, 0);
            path.lineTo(startDrawable.getIntrinsicWidth() / 2, canvas.getHeight());
            canvas.drawPath(path, paint);

但不幸的是,这段代码也填充了透明部分,看起来像黑色矩形。

我想看这样的东西。是否可以仅在图像的非透明部分内绘制黑色??

您可以创建两个不同的位图:

  1. 一个包括您的正常背景、线条、形状和您想要的任何绘图(一定要留在您选择的范围内)
  2. 一个是用于通过 "Paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.xxxxxxx))" 方法切割前一个的形状(在 Google 图像上进行 "PorterDuffXfermode" 搜索以查看所有混合可能性)

通过这种方式,您可以在普通 rectangular/squared 位图中自由绘制所需内容,最后使用自由形状(三角形、圆形等)应用蒙版(在整个位图中) ..).使用相同的技术从原始矩形版本开始创建圆形图片。

例如,这段代码创建了一个矩形位图的圆角版本:

@Nullable
public static Bitmap getRoundedBitmap(@Nullable final Bitmap bmp, final int radius) {
    if ((bmp == null) || (radius < 1)) return null;
    Bitmap cBitmap;
    if (bmp.getWidth() != radius || bmp.getHeight() != radius) {
        float cSmallest = Math.min(bmp.getWidth(), bmp.getHeight());
        float cFactor = cSmallest / radius;
        try {
            cBitmap = Bitmap.createScaledBitmap(bmp, (int)(bmp.getWidth() / cFactor), (int)(bmp.getHeight() / cFactor), true);
        } catch (Exception e) {
            cBitmap = null;
        }
    } else cBitmap = bmp;

    if (cBitmap == null) return null;

    final Bitmap cOutput = Bitmap.createBitmap(radius, radius, Bitmap.Config.ARGB_8888);
    final Canvas cCanvas = new Canvas(cOutput);

    final Paint cPaint = new Paint();
    final Rect cRect = new Rect(0, 0, radius, radius);

    cPaint.setAntiAlias(true);
    cPaint.setFilterBitmap(true);
    cPaint.setDither(true);
    cPaint.setStyle(Paint.Style.FILL);
    cCanvas.drawARGB(0, 0, 0, 0);
    cPaint.setColor(Color.BLACK);
    cCanvas.drawCircle(radius / 2f, radius / 2f, radius / 2f, cPaint);
    cPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

      //draws the rectangular Bitmap and use the special Paint object that has the circular "mask" set
    cCanvas.drawBitmap(cBitmap, cRect, cRect, cPaint);
    return cOutput;
}