Welcome to a tutorial on how to write text on images in Python. Need to add some text to an image?
We can use the Pillow Imaging Library to write text onto images in Python:
from PIL import Image, ImageFont, ImageDraw
img = Image.open("IMG.JPG")
draw = ImageDraw.draw(img)
font = ImageFont.truetype("FONT.TTF", 18)
pos = (0, 0)
color = (255, 255, 255)
draw.text(pos, "TEXT", fill=color, font=font)
img.save("SAVE.WEBP")
That covers the quick basics, but read on if you need more examples!
ⓘ I have included a zip file with all the source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.
TLDR – QUICK SLIDES
Fullscreen Mode – Click Here
TABLE OF CONTENTS
DOWNLOAD & NOTES
Firstly, here is the download link to the example code as promised.
QUICK NOTES
- Download and unzip into your project folder.
- Create a virtual environment “as usual”.
virtualenv venv
- Windows –
venv\scripts\activate
- Mac/Linux –
venv/bin/activate
- Install pillow –
pip install pillow
. - Run the examples.
EXAMPLE CODE DOWNLOAD
Click here to download all the example source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.
PYTHON WRITE TEXT ON IMAGE
All right, let us now get into the examples of writing text onto images in Python.
1) SIMPLE WRITE TEXT
# (A) IMPORT PILLOW
from PIL import Image, ImageFont, ImageDraw
# (B) SETTINGS
sImg = "demo.webp" # source image
sSave = "demoA.webp" # save as
sText = "FRIED RICE" # text to write
sFont = "Expectative.ttf" # font file
sSize = 32 # font size
sColor = (255, 255, 255) # text color
sPos = (10, 10) # write text at this position
# (C) WRITE TEXT TO IMAGE + SAVE
iOpen = Image.open(sImg)
iDraw = ImageDraw.Draw(iOpen)
iFont = ImageFont.truetype(sFont, sSize)
iDraw.text(sPos, sText, fill=sColor, font=iFont)
iOpen.save(sSave)
This is pretty much the “long-winded” version of the introduction snippet. Shouldn’t be much trouble once you trace through the code, it’s pretty much just:
- Open the image –
iOpen = Image.open(SOURCE)
- Draw on the image –
iDraw = ImageDraw.Draw(iOpen)
- Write text on the image –
iDraw.text(POSITION, TEXT, fill=COLOR, font=FONT)
- Save it –
iOpen.save(TARGET)
2) MORE TEXT OPTIONS
# (A) IMPORT PILLOW
from PIL import Image, ImageFont, ImageDraw
# (B) SETTINGS
sImg = "demo.webp" # source image
sSave = "demoB.webp" # save as
sText = "EGG\nFRIED RICE" # text to write
sFont = "Expectative.ttf" # font file
sSize = 32 # font size
sColor = (0, 0, 255, 32) # text color with opacity (alpha)
sPos = (10, 10) # write text at this position
sSpace = 20 # line spacing
sAlign = "center" # text align - left, right, center
sStrokeW = 3 # stroke width
sStrokeC = (255, 0, 0) # stroke color
# (C) WRITE TEXT TO IMAGE + SAVE
iOpen = Image.open(sImg).convert("RGBA")
iDraw = ImageDraw.Draw(iOpen)
iFont = ImageFont.truetype(sFont, sSize)
iDraw.text(sPos, sText, fill=sColor, font=iFont, spacing=sSpace, align=sAlign, stroke_width=sStrokeW, stroke_fill=sStrokeC)
iOpen.save(sSave)
Now, there is a lot more we can do with the Pillow library… I will just go through a few of the common ones here:
- For multi-line text:
- Just add a line break –
sText = "EGG\nFRIED RICE"
. - In
iDraw.text()
– We can also specifyalign="left|center|right"
, and set the line spacing –spacing=N
.
- Just add a line break –
- To set “transparent text”:
- Take note of
sColor = (0, 0, 255, 32)
, the last parameter being the alpha (opacity). - It is necessary to convert into RGBA, or the opacity will not register –
iOpen = Image.open(sImg).convert("RGBA")
.
- Take note of
- To stroke the text (add text outline):
- In
iDraw.text()
, we definestroke_width=N
andstroke_fill=(RGBA)
.
- In
3) CENTER TEXT ON IMAGE
# (A) IMPORT PILLOW
from PIL import Image, ImageFont, ImageDraw
import math
# (B) SETTINGS
sImg = "demo.webp" # source image
sSave = "demoC.webp" # save as
sText = "EGG\nFRIED RICE" # text to write
sFont = "Expectative.ttf" # font file
sSize = 32 # font size
sColor = (255, 255, 255) # text color
sStrokeW = 3 # stroke width
sStrokeC = (0, 0, 0) # stroke color
# (C) IMAGE DRAW + FONT
iOpen = Image.open(sImg)
iDraw = ImageDraw.Draw(iOpen)
iFont = ImageFont.truetype(sFont, sSize)
# (D) CALCULATE CENTER COORDINATES
iw, ih = iOpen.size # image dimensions
_, _, tw, th = iDraw.textbbox((0, 0), sText, font=iFont) # text dimensions
x = math.floor((iw - tw) / 2)
y = math.floor((ih - th) / 2)
sPos = (x, y)
# (E) WRITE TEXT TO IMAGE + SAVE
iDraw.text(sPos, sText, fill=sColor, font=iFont, stroke_width=sStrokeW, stroke_fill=sStrokeC)
iOpen.save(sSave)
Finally, centering the text on the image is sadly… Mathematical. Take note of (D), where we calculate the XY position of the text.
- Get the dimensions of the image –
iw, ih = iOpen.size
- Get the dimensions of the text box –
_, _, tw, th = iDraw.textbbox((0, 0), sText, font=iFont)
- Then in “plain English”:
x = FLOOR((IMAGE WIDTH - TEXT WIDTH) ÷ 2)
y = FLOOR((IMAGE HEIGHT - TEXT HEIGHT) ÷ 2)
EXTRA BITS & LINKS
That’s all for the tutorial, and here is a small section on some extras and links that may be useful to you.
LINKS & REFERENCES
- Pillow Image Draw – Official Documentation
- Center Text On Image – StackOverflow
INFOGRAPHIC CHEAT SHEET

THE END
Thank you for reading, and we have come to the end. I hope that it has helped you to better understand, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!