Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Positioning text using Canvas.drawText()

Tags:

android

I'm new in Android development and now trying to make a simple app. The user can choose an image and add text to it. The user can choose different fonts and text sizes. For a preview, I'm using ImageView in RelativeLayout, created text will be added to layout from code (using TextView). When user push saves button, the image will be saved with text.

All problem in Canvas.drawText. I can't find a good formula for calculating right X and Y. After drawing text is always in the wrong position. Y position always different depending on the font and X make a small indent too.

Here is screenshot (first is TextView, below is pictured text):

Screenshot

Here is my code for finding the position:

public float[] getPosition(ImageView imageView, TextView textView) {
    Matrix matrix = new Matrix();
    imageView.getImageMatrix().invert(matrix);
    float[] coord = {textView.getX(), textView.getY()+textView.getHeight()};
    matrix.mapPoints(coord);
    return coord;
}

And here is code for draw:

float[] coord = bundle.getFloatArray("coord");
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setTypeface(fontsList.get(bundle.getInt("font")));
        paint.setAlpha((int)(255*bundle.getFloat("alpha"))); 
        paint.setTextSize(bundle.getFloat("size")*bundle.getFloat("scale"));
        paint.setColor(bundle.getInt("color"));
        canvas.drawText(text, coord[0],coord[1],paint);
like image 714
Walper Avatar asked Feb 07 '23 05:02

Walper


1 Answers

The X and Y arguments for canvas.drawText() specify an origin point. The way the text is drawn, the origin's Y value is on the baseline of the text (the line on which the letters sit), and the origin's X value is either at the far left, far right, or exact center depending on the current Align setting on the Paint object.

When you call getX() and getY(), you are getting the current pixel coordinates of the top left of the TextView. This is not the origin of text being drawn by TextView. With the current Align setting, the X value is fine; however, the Y value does not match.

If you want to match your text with that of the TextView, try adding textView.getBaseline() to the value returned by getY().

It's also worth considering using one of the text layout classes (e.g. StaticLayout or DynamicLayout) to draw your text instead. In that case, it will be drawn using the canvas origin as the top-left of the drawn text, so you wouldn't need to calculate baselines.

like image 61
Karakuri Avatar answered Feb 19 '23 23:02

Karakuri