Use Python To Add Text To Image

Sharing is caring!

Last Updated on July 14, 2022 by Jay

Do you know Python can help add text to an image? Although not a graphics editing software, Python is well capable of manipulating image files. In this tutorial, we’ll put a sample text “Python In Office ©” on multiple images. Instead of doing that manually, or using some expensive software, we can achieve the same result within minutes using Python!

Library

For this tutorial, we’ll use the PILLOW library (Python Imaging Library). We can use pip to install it from the command line:

pip install Pillow

The Pillow library allows us to open, modify, and save image files.

Note that we need to import PIL instead of Pillow.

import PIL  # correct import

import Pillow # throws ModuleNotFoundError: No module named 'Pillow'

We’ll use 3 submodules from Pillow:

  • Image: A class for the image file that allows for opening and saving image files.
  • ImageDraw: A class for creating new images, we’ll use this to add text to an image.
  • ImageFont: The text font.

Read An Image File Into Python

Let’s first read an image file into Python:

from PIL import (Image, 
                 ImageFont, 
                 ImageDraw)

img = Image.open('flower.jpg')

I’m using Jupyter Notebook, which has a built-in function display() to show images inside the notebook.

Display image in Jupyter notebook
Display image in Jupyter notebook

Fonts

We can choose different fonts to add to the image. I’m going to use a font that comes with the Windows OS. To find all available fonts on your computer, type “font” in your windows search bar, then Font settings.

Windows Font Settings
Windows Font Settings

In Font settings, we can see many different fonts. We can also download new fonts from the Internet and install them for later use.

The font I want to use is called “Algerian”, and we can find the font file location from the settings.

Find font file location
Find font file location

With this font file, we can now create a font object to draw on top of an image in Python. In the below line of code:

  1. The first argument is the URL to the font file.
  2. The second argument is the font size. I’m using 300 here because the sample image is quite big.
font = ImageFont.truetype(r'C:\Windows\Fonts\ALGER.TTF',300)

Python PILLOW – Add Text To An Image

Now we need to create an ImageDraw object to modify the image. The draw.text() below takes the following arguments:

  • (10, 10) – the (x,y) coordinates of the starting position
  • font – the ImageFont we just created
  • fill – the RGB color value of the text (255 means white, 0 means black)
draw = ImageDraw.Draw(img)
draw.text((10,10),'Python In Office ©', font = font, fill = (255,255,255))

Note: the ImageDraw object actually modifies the Image object. To show the updated image, we can use display(img) again:

Add text to an image using Python
Add text to an image using Python

Putting Text On Bottom Right Corner

To put the text in the bottom right corner, we need to do a couple of things:

  1. Determine the size of the text, this should be set dynamically since each image will have different size.
  2. Also, dynamically determine the starting (x,y) coordinates for the text. The coordinates will vary given different image sizes.

We can get the image (i.e. canvas) size by calling the size attribute. In this example, our image is 3651 pixels wide and 2664 pixels tall.

Image size in pixels
Image size in pixels

We are going to set the text size such that the whole text line will take roughly 1/3 of the width of the image.

The default font size of an ImageFont object is size 10. To get the text dimensions (width and height) and also calculate the scaling factor:

default_font_size = 10
text = 'Python In Office ©'
text_width, text_height = ImageFont.truetype(r'C:\Windows\Fonts\ALGER.TTF').getsize(text)

## load image
img = Image.open('flower.jpg')

## get image dimensions
img_width, img_height = img.size

## calculate scaler such that the text takes about 1/3 of the image width
scaler = img_width/3/text_width

scaler
19.21578947368421

For this example, the scaler worked out to be roughly 19, which means our font size will be 10 * 19 = 190. The text width and height will also scale accordingly.

## Scale text font size, width and height
## used to find the starting x,y coordinates
 
scale_text_font = int(default_font_size * scaler)
scale_text_width = int(scaler * text_width)
scale_text_height = int(scaler * text_height)

## create font object with appropriate font size
font = ImageFont.truetype(r'C:\Windows\Fonts\ALGER.TTF', size = scale_text_font)

## re-draw new image and place text on it
draw = ImageDraw.Draw(img)

## starting x,y coords for the text
start_x = img_width - scale_text_width - 20
start_y = img_height - scale_text_height - 20

draw.text((start_x,start_y), text = text, font = font, fill = (255,255,255))
img.save('flower_w_text.jpg')

Adding Text To Multiple Images

To add text to multiple images, let’s place all images into the same folder. Then we can use os.listdir() to get all file names from the folder and process each one. The complete code is as follows:


import os
from PIL import (Image, 
                 ImageFont, 
                 ImageDraw)


## By: Jay @ Pythoninoffice
default_font_size = 10
text = 'Python In Office ©'
text_width, text_height = ImageFont.truetype(r'C:\Windows\Fonts\ALGER.TTF').getsize(text)
folder_path = r'C:\Users\jay\Desktop\PythonInOffice\python_add_text_to_multiple_images\images'

for f in os.listdir(folder_path):
    img = Image.open(rf'{folder_path}\{f}')
    img_width, img_height = img.size
    scaler = img_width/2/text_width

    scale_text_font = int(default_font_size * scaler)
    scale_text_width = int(scaler * text_width)
    scale_text_height = int(scaler * text_height)

    font = ImageFont.truetype(r'C:\Windows\Fonts\ALGER.TTF', size=scale_text_font)

    draw = ImageDraw.Draw(img)
    start_x = img_width - scale_text_width - 20
    start_y = img_height - scale_text_height - 20
    draw.text((start_x,start_y), text = text, font = font, fill = (0,0,0))
    file_name = f.split('.')[0] + '_w_text.jpg'
    img.save(rf'{folder_path}\{file_name}')
## By: Jay @ Pythoninoffice

Below is an example of what the text looks like on images of different sizes.

Use Python To Add Text On Images Of Different Sizes
Use Python To Add Text On Images Of Different Sizes

Additional Resources

How to Make a WordCloud in Python

Create Excel Pixel Art With Python

Leave a Reply

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