Write Text To Image In Python (Simple Examples)

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

Source code on GitHub Gist

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

1_basic.py
# (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

2_more.py
# (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 specify align="left|center|right", and set the line spacing – spacing=N.
  • 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").
  • To stroke the text (add text outline):
    • In iDraw.text(), we define stroke_width=N and stroke_fill=(RGBA).

 

 

3) CENTER TEXT ON IMAGE

3_center.py
# (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

 

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!

Leave a Comment

Your email address will not be published. Required fields are marked *