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!
TABLE OF CONTENTS
DOWNLOAD & NOTES
Here is the download link to the example code, so you don’t have to copy-paste everything.
EXAMPLE CODE DOWNLOAD
Just click on “download zip” or do a git clone. I have released it under the MIT license, so feel free to build on top of it or use it in your own project.
SORRY FOR THE ADS...
But someone has to pay the bills, and sponsors are paying for it. I insist on not turning Code Boxx into a "paid scripts" business, and I don't "block people with Adblock". Every little bit of support helps.
Buy Me A Coffee Code Boxx eBooks
PYTHON WRITE TEXT ON IMAGE
All right, let us now get into the examples of writing text onto images in Python.
QUICK SETUP
- Create a virtual environment
virtualenv venv
and activate it –venv\Scripts\activate
(Windows)venv/bin/activate
(Linux/Mac) - Install required libraries –
pip install pillow
1) SIMPLE WRITE TEXT
# (A) IMPORT PILLOW
from PIL import Image, ImageFont, ImageDraw
# (B) SETTINGS
sImg = "demo.png" # source image
sSave = "demoA.webp" # save as
sText = "FRIED RICE" # text to write
sFont = "C:/Windows/Fonts/arial.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.png" # source image
sSave = "demoB.webp" # save as
sText = "EGG\nFRIED RICE" # text to write
sFont = "C:/Windows/Fonts/arial.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.png" # source image
sSave = "demoC.webp" # save as
sText = "EGG\nFRIED RICE" # text to write
sFont = "C:/Windows/Fonts/arial.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)
EXTRAS
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
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!