如何使用画布(canvas)绘制带有背景颜色的文本

17

我有一些代码,在位图(画布)上绘制文本

canvas.drawTextOnPath(Text, textPath[count], gipa, -10, text);

请问,在使用路径(textPath)绘制文本时,是否可以设置背景颜色?

这是用于仅绘制文本的完整函数。

 public void drawText(float x,float y ,String Text,Canvas canvas,Paint paint1 ,int count )
        {
            float xren =text.measureText(Text.trim());

            canvas.drawTextOnPath(Text, textPath[count], gipa, -10, text);

        }

使用这个函数我可以在我的画布上绘制文本。那么如何修改这个函数以便用背景来绘制这段文本呢?


你是指测试应该有颜色还是画布应该有颜色? - Rajdeep Dua
画布上有位图(图片),我使用drawTextOnPath函数在该图像上绘制文本(因为我需要这个功能来绘制)。我想要为此文本(例如绿色文本颜色)仅绘制背景(例如黑色)。 - Peter
你不能只用一条所需的背景颜色的线来绘制路径,然后在其上绘制文本吗?这可能需要将路径插入一点。 - js-
好的,你能提供一些代码吗,教我如何在路径上绘制线条(或矩形)并附带文本吗?谢谢。 - Peter
4个回答

20

这里可能需要两个步骤。首先,您需要使用背景颜色绘制路径线,并设置一个画笔对象的线条粗度。然后再按指示绘制文本。同样,更改画笔的样式可以帮助达到所需效果。尝试使用FILLSTROKEFILL_AND_STROKE来获得不同的效果。

mpaint.setStyle(Paint.Style.STROKE);
mpaint.setStrokeWidth(strokeWidth);

添加了一个样例,用红色绘制一个路径(矩形):

         Paint mPaint = new Paint();
         mPaint.setColor(Color.RED);
         Path mPath = new Path();
         RectF mRectF = new RectF(20, 20, 240, 240);
         mPath.addRect(mRectF, Path.Direction.CCW);
         mPaint.setStrokeWidth(20);
         mPaint.setStyle(Paint.Style.STROKE);
         canvas.drawPath(mPath, mPaint);

然后沿着相同的路径绘制文本(蓝色):

        mPaint.setColor(Color.BLUE);
         mPaint.setStrokeWidth(0);
         mPaint.setStyle(Paint.Style.FILL);
         mPaint.setTextSize(20);
         canvas.drawTextOnPath("Draw the text, with origin at (x,y), using the specified paint, along the specified path.", mPath, 0, 5, mPaint);

results


感谢您给了我正确的方向。最终我将文本涂了两次。首先使用描边,然后用文本覆盖它。没有计算或繁重的工作。 - Abandoned Cart

10

如果你想要像这样做,请实现下面的代码片段:

输入图像描述

     /**
     * PUT THIS METHOD FOR IMPLEMENT WATER-MARK IN COMMON FILE
     */
    public static Bitmap waterMark(Bitmap src, String watermark) {
        //get source image width and height
        int w = src.getWidth();
        int h = src.getHeight();

        Bitmap result = Bitmap.createBitmap(w, h, src.getConfig());
        Canvas canvas = new Canvas(result);
        canvas.drawBitmap(src, 0, 0, null);
        Paint paint = new Paint();
        Paint.FontMetrics fm = new Paint.FontMetrics();
        paint.setColor(Color.WHITE);
        paint.getFontMetrics(fm);
        int margin = 5;
        canvas.drawRect(50 - margin, 50 + fm.top - margin,
                50 + paint.measureText(watermark) + margin, 50 + fm.bottom
                        + margin, paint);

        paint.setColor(Color.RED);

        canvas.drawText(watermark, 50, 50, paint);
        return result;
    }

//获取URI中的位图:

  private Bitmap getBitmapFromUri(String photoPath) {
        Bitmap image = null;
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
        Bitmap bitmap = BitmapFactory.decodeFile(photoPath, options);
        return bitmap;
    }

// 保存图片:

 private String SaveImage(Bitmap finalBitmap) {

        String root = Environment.getExternalStorageDirectory().toString();
        File myDir = new File(root + "/shareImage");
        myDir.mkdirs();
        Random generator = new Random();
        int n = 10000;
        n = generator.nextInt(n);
        String fname = "Image" + n + ".jpg";

        File file = new File(myDir, fname);
        if (file.exists()) file.delete();
        try {
            FileOutputStream out = new FileOutputStream(file);
            finalBitmap.compress(Bitmap.CompressFormat.JPEG, 20, out);
            out.flush();
            out.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return file.getAbsolutePath();
    }

// 像这样调用:

                Bitmap bitmap = getBitmapFromUri(attachment.get(i).getPath()); // Enter here your Image path

                Bitmap bitmapp = waterMark(bitmap, "ENTER YOUR TEXT FOR WATERMARK LABEL");

                String path = SaveImage(bitmapp);
                Uri uri = Uri.fromFile(new File(path));

现在,您可以从URI中获取新实现的水印图像了。

希望这能帮到您。


6

我认为这种解决方案比drawPath更好,更灵活。

使用此方法计算文本背景的大小:

private @NonNull Rect getTextBackgroundSize(float x, float y, @NonNull String text, @NonNull TextPaint paint) {
    Paint.FontMetrics fontMetrics = paint.getFontMetrics();
    float halfTextLength = paint.measureText(text) / 2 + 5;
    return new Rect((int) (x - halfTextLength), (int) (y + fontMetrics.top), (int) (x + halfTextLength), (int) (y + fontMetrics.bottom));
}

然后以Rect的形式绘制背景:

Rect background = getTextBackgroundSize(x, y, text, textPaint);
canvas.drawRect(background, bkgPaint);
canvas.drawText(text, x, t, textPaint);

简单易调。谢谢! - Andrew Koster
你可以在创建矩形后,使用RectF.inset(...)来移除+5并调整结果矩形,以创建边距,这将使你更好地控制它们。 - A. Steenbergen

1

我创建了这个方法,它将让您更好地了解如何轻松完成这项任务。

  public static Drawable getTextToDrawable(final String sText, final float    textSize, final int textColor, final int bgColor, final int imageSize) {

    Shape shape = new Shape() {

        @Override
        public void draw(Canvas canvas, Paint paint) {
            paint.setTextSize(spToPixel(textSize));
            int ivImageSize = SUtils.dpToPx(imageSize);
            paint.setTextAlign(Paint.Align.LEFT);
            float baseline = -paint.ascent(); // ascent() is negative
            int width = (int) (paint.measureText(sText)); // round
            int height = (int) (baseline + paint.descent());
            Bitmap image = Bitmap.createBitmap(ivImageSize, (int) (ivImageSize), Bitmap.Config.ARGB_8888);
            canvas.drawBitmap(image, ivImageSize, ivImageSize, paint);
            paint.setColor(bgColor);
            if (sText != null) {
                if (sText.length() < 3) {

                    canvas.drawCircle(ivImageSize / 2, ivImageSize / 2, ivImageSize / 2, paint);
                    paint.setColor(textColor);
                    canvas.drawText(sText, (ivImageSize - width) / 2, (height+baseline)/2, paint);
                } else {
                    canvas.drawRect(0, 0, ivImageSize, height, paint);
                    paint.setColor(textColor);
                    canvas.drawText(sText, (ivImageSize - width) / 2, baseline, paint);

                }
            }
        }
    };
    return new ShapeDrawable(shape);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接