Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

center text vertically and horizontally with canvas

I'm trying to align a text in bitmap horizontally and vertically, I read several post but I can't find a solution. The bitmap is a simple image of a circle. I post my current code. More or less it works but the text is not perfectly centered, it seems a bit on the left and a bit on the top, I mean it seems I have to add an offset to move it to the right and to the bottom.

public static float convertDpToPixel(float dp, Context context) {
     Resources resources = context.getResources();
     DisplayMetrics metrics = resources.getDisplayMetrics();
     float px = dp * (metrics.densityDpi / 160f);
     return px;
}    

v = (ImageView) findViewById(R.id.imageView1);
Bitmap b = BitmapFactory.decodeResource(getResources(),
               R.drawable.marker).copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(b);
Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
textPaint.setARGB(255, 0, 0, 0);
textPaint.setTextAlign(Align.CENTER);
textPaint.setTypeface(Typeface.DEFAULT_BOLD);
textPaint.setTextSize(convertDpToPixel(9, this));

String text = "30";
int xPos = (canvas.getWidth() / 2);
int yPos = (int) ((canvas.getHeight() / 2) - ((textPaint.descent() +
               textPaint.ascent()) / 2)) ;

canvas.drawText(text, xPos, yPos, textPaint);
v.setImageBitmap(b);
like image 902
greywolf82 Avatar asked Feb 27 '14 18:02

greywolf82


People also ask

How do you center text horizontally and vertically?

To center both vertically and horizontally, use padding and text-align: center : I am vertically and horizontally centered.

How do you center text on canvas?

To align HTML5 Canvas text, we can use the textAlign property of the canvas context, which can be set to start, end, left, center, or right. The alignment is relative to an imaginary vertical line at the x position of the text defind by fillText() or strokeText().


2 Answers

The problem is that you're currently not considering the width and height of the text. If your text is "hello" or "THIS A STRING" you just treat it equally, so that's wrong.

You need to calculate the width and the height of the text, and then shift the text position by half those distances.

For example to center vertically:

Rect r = new Rect();
paint.getTextBounds(text, 0, text.length(), r);
yPos += (Math.abs(r.height()))/2;    // or maybe -= instead of +=, depends on your coordinates

I hope this takes you into the right direction.

EDIT: The origin is interpreted based on the Align setting in the paint. You're using

 textPaint.setTextAlign(Align.CENTER);

So you probably don't need to do any calculations to center horizontally (meaning that for horizontal origin you should use the code you already had).

 int xPos = (canvas.getWidth() / 2);
like image 75
Merlevede Avatar answered Oct 13 '22 23:10

Merlevede


As @Merlevede says, if you align the textPaint to CENTER, you just need to do:

canvas.drawText(
    text,
    canvas.getWidth() / 2,
    ((canvas.getHeight() / 2) - ((textPaint.descent() + textPaint.ascent()) / 2)),
    textPaint
);
like image 41
cesards Avatar answered Oct 14 '22 00:10

cesards