Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python PIL draw multiline text on image

I try to add text at the bottom of image and actually I've done it, but in case of my text is longer then image width it is cut from both sides, to simplify I would like text to be in multiple lines if it is longer than image width. Here is my code:

FOREGROUND = (255, 255, 255) WIDTH = 375 HEIGHT = 50 TEXT = 'Chyba najwyższy czas zadać to pytanie na śniadanie \n Chyba najwyższy czas zadać to pytanie na śniadanie' font_path = '/Library/Fonts/Arial.ttf' font = ImageFont.truetype(font_path, 14, encoding='unic') text = TEXT.decode('utf-8') (width, height) = font.getsize(text)  x = Image.open('media/converty/image.png') y = ImageOps.expand(x,border=2,fill='white') y = ImageOps.expand(y,border=30,fill='black')  w, h = y.size bg = Image.new('RGBA', (w, 1000), "#000000")  W, H = bg.size xo, yo = (W-w)/2, (H-h)/2 bg.paste(y, (xo, 0, xo+w, h)) draw = ImageDraw.Draw(bg) draw.text(((w - width)/2, w), text, font=font, fill=FOREGROUND)   bg.show() bg.save('media/converty/test.png') 
like image 268
user985541 Avatar asked Oct 08 '11 16:10

user985541


2 Answers

You could use textwrap.wrap to break text into a list of strings, each at most width characters long:

import textwrap lines = textwrap.wrap(text, width=40) y_text = h for line in lines:     width, height = font.getsize(line)     draw.text(((w - width) / 2, y_text), line, font=font, fill=FOREGROUND)     y_text += height 
like image 195
unutbu Avatar answered Sep 18 '22 12:09

unutbu


The accepted answer wraps text without measuring the font (max 40 characters, no matter what the font size and box width is), so the results are only approximate and may easily overfill or underfill the box.

Here is a simple library which solves the problem correctly: https://gist.github.com/turicas/1455973

like image 21
pryma Avatar answered Sep 18 '22 12:09

pryma