Skip to content

Instantly share code, notes, and snippets.

@destan
Last active January 10, 2024 06:32
Show Gist options
  • Star 44 You must be signed in to star a gist
  • Fork 12 You must be signed in to fork a gist
  • Save destan/5540702 to your computer and use it in GitHub Desktop.
Save destan/5540702 to your computer and use it in GitHub Desktop.
Python text to image (png) conversion with automatic new line calculation
# coding=utf8
import PIL
from PIL import ImageFont
from PIL import Image
from PIL import ImageDraw
def text2png(text, fullpath, color = "#000", bgcolor = "#FFF", fontfullpath = None, fontsize = 13, leftpadding = 3, rightpadding = 3, width = 200):
REPLACEMENT_CHARACTER = u'\uFFFD'
NEWLINE_REPLACEMENT_STRING = ' ' + REPLACEMENT_CHARACTER + ' '
#prepare linkback
linkback = "created via http://ourdomain.com"
fontlinkback = ImageFont.truetype('font.ttf', 8)
linkbackx = fontlinkback.getsize(linkback)[0]
linkback_height = fontlinkback.getsize(linkback)[1]
#end of linkback
font = ImageFont.load_default() if fontfullpath == None else ImageFont.truetype(fontfullpath, fontsize)
text = text.replace('\n', NEWLINE_REPLACEMENT_STRING)
lines = []
line = u""
for word in text.split():
print word
if word == REPLACEMENT_CHARACTER: #give a blank line
lines.append( line[1:] ) #slice the white space in the begining of the line
line = u""
lines.append( u"" ) #the blank line
elif font.getsize( line + ' ' + word )[0] <= (width - rightpadding - leftpadding):
line += ' ' + word
else: #start a new line
lines.append( line[1:] ) #slice the white space in the begining of the line
line = u""
#TODO: handle too long words at this point
line += ' ' + word #for now, assume no word alone can exceed the line width
if len(line) != 0:
lines.append( line[1:] ) #add the last line
line_height = font.getsize(text)[1]
img_height = line_height * (len(lines) + 1)
img = Image.new("RGBA", (width, img_height), bgcolor)
draw = ImageDraw.Draw(img)
y = 0
for line in lines:
draw.text( (leftpadding, y), line, color, font=font)
y += line_height
# add linkback at the bottom
draw.text( (width - linkbackx, img_height - linkback_height), linkback, color, font=fontlinkback)
img.save(fullpath)
#show time
text2png(u"This is\na\ntest şğıöç zaa xd ve lorem hipster", 'test.png', fontfullpath = "font.ttf")
@peterkodermac
Copy link

Thanks for this, helped me out.

I was able to solve the TODO on line 37, by using textwrap. Just import it and set the maximum width. Something like:
list=textwrap.wrap(text, width=30)

@UmutAlihan
Copy link

How can I change the code in order to print not word by word but line by line...

With this script at every word it is like putting an \n to the end of the each word

Can you show me where in the script this is happenning?

@Salzie
Copy link

Salzie commented Dec 18, 2017

Can we input a txt file instead of a single line, where it converts a few lines of code in an image that looks like a screenshot of the txt file?

@haemi
Copy link

haemi commented Jun 28, 2018

is it possible to use emojis in the text? Currently they are replaced by rectangles...

@muiton
Copy link

muiton commented Feb 1, 2019

@haemi emoji can be used if can include emoji font here.

@Cahmaduom5
Copy link

Hi there, can someone help me with this code I am trying to convert my text file into images? will be thankful for the act.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment