Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correctly centring text (PIL/Pillow)

I'm drawing some text on a black strip, and then pasting the result on top of a base image, using PIL. One criticality is having the text position perfectly in the center of the black strip.

I cater for that via the following code:

from PIL import Image, ImageFont, ImageDraw

background = Image.new('RGB', (strip_width, strip_height)) #creating the black strip
draw = ImageDraw.Draw(background)
font = ImageFont.truetype("/usr/share/fonts/truetype/freefont/FreeSansBold.ttf", 16)
text_width, text_height = draw.textsize("Foooo Barrrr!")
position = ((strip_width-text_width)/2,(strip_height-text_height)/2)
draw.text(position,"Foooo Barrrr!",(255,255,255),font=font)
offset = (0,base_image_height/2)
base_image.paste(background,offset)

Notice how I'm setting position.

Now with all said and done, the result looks like so:

enter image description here

The text isn't precisely middled. It's slightly to the right and down. How do I improve my algorithm?

like image 502
Hassan Baig Avatar asked May 02 '17 05:05

Hassan Baig


1 Answers

Remember to pass your font to draw.textsize as a second parameter (and also make sure you are really using the same text and font arguments to draw.textsize and draw.text).

Here's what worked for me:

from PIL import Image, ImageFont, ImageDraw

def center_text(img, font, text, color=(255, 255, 255)):
    draw = ImageDraw.Draw(img)
    text_width, text_height = draw.textsize(text, font)
    position = ((strip_width-text_width)/2,(strip_height-text_height)/2)
    draw.text(position, text, color, font=font)
    return img

Usage:

strip_width, strip_height = 300, 50
text = "Foooo Barrrr!!"

background = Image.new('RGB', (strip_width, strip_height)) #creating the black strip
font = ImageFont.truetype("times", 24)
center_text(background, font, "Foooo Barrrr!")

Result:

fooobarrrr

like image 159
tiwo Avatar answered Sep 26 '22 00:09

tiwo