Pillow ImageDraw text coordinates to center
Asked Answered
R

2

8

The code below brings the text in the center of x, but i don't know how to calculate the center for the y coordinate... it is not (imgH-h)/2!

(The right y-coordinate is -80)

from PIL import Image, ImageDraw, ImageFont

font= './fonts/BebasNeue-Regular.ttf'
color = (255, 244, 41)
text = 'S'

img = Image.new('RGB', (500, 500), color=(255, 255, 255))
imgW, imgH = img.size
fnt = ImageFont.truetype(font, 600)
d = ImageDraw.Draw(img)

w, h = d.textsize(text, fnt)

nullH = (imgH-h)
print(imgH, h)

d.text(((imgW-w)/2, nullH), text, font=fnt, fill=color)

img.show()

screenshot of execution of code

Replete answered 23/11, 2019 at 13:48 Comment(0)
P
13

It seems related to an old Pillow bug. You need to add the offset to the textsize. This works for me:

from PIL import Image, ImageDraw, ImageFont

color = (255, 244, 41)
text = 'S'

N = 500
size_image = width_image, height_image = N, N

img = Image.new('RGB', size_image, color='white')
font_path = './fonts/BebasNeue-Regular.ttf'
font = ImageFont.truetype(font_path, size=600)
draw = ImageDraw.Draw(img)
width_text, height_text = draw.textsize(text, font)

offset_x, offset_y = font.getoffset(text)
width_text += offset_x
height_text += offset_y

top_left_x = width_image / 2 - width_text / 2
top_left_y = height_image / 2 - height_text / 2
xy = top_left_x, top_left_y

draw.text(xy, text, font=font, fill=color)

img.show()
Putscher answered 23/11, 2019 at 15:2 Comment(1)
Thanks ! , your solution solved my problem too.Gilgilba
C
0

Just wanted to mention that textsize is now depricated. Using textbbox worked for me to get text_width and text_height. I think the bug is no longer there because (imgH-h)/2 worked for me.

...

# Get width and height
 _, _, text_width, text_height = d.textbbox(xy=(0, 0), text=text, font=fnt)

# Center text
x_text = (image_width - text_width) / 2
y_text = (image_height - text_height ) / 2

d.text((x_text, y_text), text=text, font=fnt, fill=color)
...

Couldst answered 23/1 at 22:13 Comment(1)
Or you can just use d.text((image_width / 2, image_height / 2), text=text, font=fnt, fill=color, anchor="mm").Erode

© 2022 - 2024 — McMap. All rights reserved.