Reputation: 15824
I'm writing text atop a black strip, and then pasting the said strip on a base image. It's working perfectly.
My problem is that if the text has lots of characters, it overflows outside the base image. Here's what I mean:
How do I fix my code such that the overflowing text goes to the next line?
Here's what I'm currently doing:
background = Image.new('RGBA', (base_width, BACKGROUND_HEIGHT),(0,0,0,128)) #creating the black strip
draw = ImageDraw.Draw(background)
font = ImageFont.truetype("/usr/share/fonts/truetype/freefont/FreeSansBold.ttf", 16)
text = "Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar"
text_width, text_height = draw.textsize(text,font=font)
position = ((base_width-text_width)/2,(BACKGROUND_HEIGHT-text_height)/2)
draw.text(position,text,(255,255,255),font=font)
offset = (0,base_height/2)
img.paste(background,offset,mask=background)
Upvotes: 3
Views: 2433
Reputation: 15824
I ended up writing the following to ensure text comfortably flows to the next line. It would be great if someone can help me optimize this rather inelegant code:
base_width, base_height = img.size
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", font_size)
line = ""
lines = []
width_of_line = 0
number_of_lines = 0
# break string into multi-lines that fit base_width
for token in text.split():
token = token+' '
token_width = font.getsize(token)[0]
if width_of_line+token_width < base_width:
line+=token
width_of_line+=token_width
else:
lines.append(line)
number_of_lines += 1
width_of_line = 0
line = ""
line+=token
width_of_line+=token_width
if line:
lines.append(line)
number_of_lines += 1
# create a background strip for the text
font_height = font.getsize('|')[1]
background = Image.new('RGBA', (base_width, font_height*number_of_lines),(0,0,0,146)) #creating the black strip
draw = ImageDraw.Draw(background)
y_text = 0#h
# render each sentence
for line in lines:
width, height = font.getsize(line)
draw.text(((base_width - width) / 2, y_text), line, font=font, fill=fillcolor)
y_text += height
# paste the result on the base_image
offset = (0,base_height/2) #get from user input (e.g. 'top', 'bottom', 'middle')
img.paste(background,offset,mask=background)
Note: for reasons explained here, using Python's textwrap()
module yields a sub-optimal result. It's not a viable solution.
Upvotes: 2