Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python pil draw text offset

I tried to draw a character on an image with Python PIL. With the function ImageDraw.Draw.text(), the xy parameter points to the left-top corner of text. However I set xy to (0,0), the character haven't been draw the the left-top of images.

from PIL import ImageFont, ImageDraw, Image 

imageSize=(40,40)
mage = Image.new("RGB", imageSize, (0,0,0))
draw = ImageDraw.Draw(image)
txt = "J"
font = ImageFont.truetype("ANTQUAB.ttf",35)
draw.text((0,0), txt, font=font) 

why?

like image 203
user3596643 Avatar asked Jan 31 '26 03:01

user3596643


2 Answers

Looks like there are font-specific offsets; you can get the vertical offset from the "top" value returned from FreeTypeFont.getbbox(). Subtracting this offset from your y-coordinate on the draw.text call will align top of text with top of image.

from PIL import ImageFont, ImageDraw, Image

text = 'J'
font = "arial.ttf"
fontsize = 12

img_w = 100
img_h = 100
canvas = Image.new('RGBA', size=(img_w,img_h), color='white')
draw = ImageDraw.Draw(canvas)
y_text = 0

font_obj = ImageFont.truetype(font, fontsize)
(left, top, right, bottom) = font_obj.getbbox(text)

x_pos = 0
y_pos = 0

# offset the y coordinate in the draw call by the "top" parameter fromgetbbox; this is the font-specific text padding
draw.text(xy=(x_pos, y_pos-top), 
            text=text, 
            font=font_obj,
            align='left', 
            fill='black')

canvas.show()
like image 124
Steve_datasci Avatar answered Feb 01 '26 16:02

Steve_datasci


The xy parameter of draw.text() is the top left corner of the text (docs), however the font might have some padding around the text, especially vertically. What I did was set the y part of the tuple to a negative number (maybe somewhere around -5?) and it worked for me.

like image 30
abacles Avatar answered Feb 01 '26 17:02

abacles