Malte
Malte

Reputation: 347

PIL: Can't vertically align text accurately despite taking font into account

I want to create a simple Python script that let's me create an image file and place a word dead-center on that canvas. However, while I can get the word to align horizontally, I just can't get it to the center vertically. I am on MacOS btw. I have tried this so far:

import os
from PIL import Image, ImageDraw, ImageFont
font_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'fonts')
font = ImageFont.truetype(os.path.join(font_path, "Verdana.ttf"), 80)
W, H = (1200,200)
msg = "hola"
im = Image.new("RGB",(W,H),(255,255,255))
draw = ImageDraw.Draw(im)
w, h = draw.textsize(msg, font)
draw.text(((W-w)/2,(H-h)/2), msg, font=font, fill="black")
im.save("output_script.png", "PNG")

I already considered the font in the textsize calculation. But the word still appears roughly 5-10% below the middle. Any ideas?

Upvotes: 2

Views: 846

Answers (2)

spiky
spiky

Reputation: 423

ImageFont.getmask(txt) returns the alpha mask bitmap with which text can be centered in the image.

import Image, ImageFont

img = Image.new('L', (32, 32), color=0)
img_w, img_h = img.size

font = ImageFont.truetype('/path/to/font.ttf', 16)
mask = font.getmask('hola') # your text here
mask_w, mask_h = mask.size

d = Image.core.draw(img.im, 0)
d.draw_bitmap(((img_w - mask_w)/2, (img_h - mask_h)/2), mask, 255) # last arg is pixel intensity of text

img.save('test.png')

Upvotes: 0

Veedrac
Veedrac

Reputation: 60207

textsize seems to return the size of the actual text, not that of the line. So it's smaller for ooo than for XXX!

I think you should just use 80 — the size you gave PIL — for the height, although I can't guarantee that it's correct.

Upvotes: 1

Related Questions