[Image-SIG] Here is code for wrapping draw.text to fit within given
pixel width
Caleb Hattingh
caleb.hattingh at gmail.com
Tue Dec 7 20:27:50 CET 2004
Hi
I wrote the code below for the purpose of wrapping text to fit within
a given pixel width:
Args:
drawer: Instance of "ImageDraw.Draw()"
text: string of long text to be wrapped
font: instance of ImageFont (I use .truetype)
containerWidth: number of pixels text lines have to fit into.
Outputs described after code below:
***code***
def IntelliDraw(drawer,text,font,containerWidth):
words = text.split()
lines = [] # prepare a return argument
lines.append(words)
finished = False
line = 0
while not finished:
thistext = lines[line]
newline = []
innerFinished = False
while not innerFinished:
#print 'thistext: '+str(thistext)
if drawer.textsize(' '.join(thistext),font)[0] > containerWidth:
# this is the heart of the algorithm: we pop words off
the current
# sentence until the width is ok, then in the next outer loop
# we move on to the next sentence.
newline.insert(0,thistext.pop(-1))
else:
innerFinished = True
if len(newline) > 0:
lines.append(newline)
line = line + 1
else:
finished = True
tmp = []
for i in lines:
tmp.append( ' '.join(i) )
lines = tmp
(width,height) = drawer.textsize(lines[0],font)
return (lines,width,height)
***endcode***
Outputs of function:
lines: list of strings which corresponds to the given "text"
argument, but broken up into list elements.
width: pixel width of the first line (should be less than containerWidth)
height: pixel height of first line (used for spacing successive lines)
An example of how this is used is given below:
***code***
text = 'One very extremely long string that cannot possibly fit \
into a small number of pixels of horizontal width, and the idea \
is to break this text up into multiple lines that can be placed like \
a paragraph into our image'
draw = ImageDraw.Draw(OurImagePreviouslyDefined)
font = fontpath = ImageFont.truetype('/usr/local/share/fonts/ttf/times.ttf',26)
pixelWidth = 500 # pixels
lines,tmp,h = IntelliDraw(draw,text,font,pixelWidth)
j = 0
for i in lines:
draw.text( (0,0+j*h), i , font=font16, fill='black')
j = j + 1
***endcode***
Hopefully this code works for you. As you may observe, the algorithm
is *extremely* simple and not optimal in any way. I would have loved
to have found something like this on the net, but couldn't, so maybe
someone else on this list is also looking.
Thanks
Caleb
More information about the Image-SIG
mailing list