Jason G
Jason G

Reputation: 200

Pillow, centering of text not working, how is this accomplished?

I have tested the calculations and the math is correct (and takes into account the height and width of the font), but after Python creates the image and I put it into Photoshop, the vertical and horizontal centering of the text is not correct. Should I be doing something else with my code?

from PIL import Image, ImageDraw, ImageFont

# base = Image.open("Images/Phones/KK17018_Navy_KH10089.jpg").convert("RGBA")
base = Image.open('Images/Tablets/KK17076_Hunter_KH235.jpg').convert('RGB')

# Create blank rectangle to write on
draw = ImageDraw.Draw(base)

message = 'GGS'
num1, num2 = base.size
bounding_box = [0, 0, num1, num2]
x1, y1, x2, y2 = bounding_box  # For easy reading

# font = ImageFont.truetype('Fonts/Circle/Circle Monograms Three White.ttf', size=413)


font = ImageFont.truetype('Fonts/Modern/Vhiena_Monoline.otf', size=800)
font2 = ImageFont.truetype('Fonts/Modern/Vhiena_Base.otf', size=800)
font3 = ImageFont.truetype('Fonts/Modern/Vhiena_Extrude A.otf', size=800)

# Calculate the width and height of the text to be drawn, given font size
w, h = draw.textsize(message, font=font3)


# Calculate the mid points and offset by the upper left corner of the bounding box
x = (x2 - x1 - w) / 2 + x1
y = (y2 - y1 - h) / 2 + y1

# Write the text to the image, where (x,y) is the top left corner of the text

draw.text((x, y), message, align='center', font=font3, fill='orange')
draw.text((x, y), message, align='center', font=font2, fill='black')
draw.text((x, y), message, align='center', font=font, fill='white')

# Draw the bounding box to show that this works
# draw.rectangle([x1, y1, x2, y2])

base.show()
base.save('test_image.jpg')

The text's upper left x,y coordinates should be (874,1399.5), but in Photoshop, they show as (875,1586). The Python code above does calculate (874,1399.5) correctly, but something is placing the font lower than it should be.

Also, I'm stacking fonts like this because it gives a regular font, a shadow font and a font that makes it look beveled in the middle of the font. Would there be a better method or is stacking fonts an ok practice?

EDIT: Upon further testing, something is adding a 22% top margin to the font as the font size increases. I could account for this, but this seems rather odd.

Upvotes: 3

Views: 1428

Answers (1)

CrazyChucky
CrazyChucky

Reputation: 3518

I don't have your exact font handy to test, but this is probably because Pillow's textsize and text methods, by default, anchor to the ascender height instead of the actual rendered top; see this note in the docs. Try using textbbox instead of textsize, and specifying the top anchor in both that and the text method, and see if that behaves more intuitively.

Note that you could probably just anchor the text to 'mm', middle/middle, to center it based on the coordinates of the image's midpoint. This anchors vertically to halfway between the ascenders and descenders, though, so it may not actually look centered, depending on the font and what glyphs you render.

Upvotes: 2

Related Questions