Python: How to write text to image using Pillow

Updated: January 7, 2024 By: Guest Contributor Post a comment

Overview

Pillow is a popular Python imaging library that extends the capabilities of the native Python Imaging Library (PIL). It enables you to perform a variety of imaging operations, including writing text over images – a step-by-step process we’ll explore in this tutorial.

Getting Started with Pillow

Before adding text to images, you need to install Pillow. You can do it using pip:

pip install Pillow

Once installed, import the required classes:

from PIL import Image, ImageDraw, ImageFont

These classes let you open images, draw on them, and define fonts.

Adding Basic Text to an Image

Let’s start with a simple example that adds text to an existing image:


from PIL import Image, ImageDraw, ImageFont

# Load an image
image = Image.open('path/to/image.jpg')

# Initialize the drawing context
draw = ImageDraw.Draw(image)

# Set font properties
font = ImageFont.truetype('arial.ttf', size=45)

# Position of the text
(x, y) = (50, 50)
text_color = 'rgb(255, 255, 255)' # white

# Draw the text on the image

draw.text((x, y), 'Hello World!', fill=text_color, font=font)

# Save the image
image.save('image_with_text.jpg')

This code snippet opens an image, sets a font, specifies the text position and color, and then writes ‘Hello World!’ on the image. Finally, it saves the new image.

Advanced Text Rendering: Handling Text Size and Wrapping

What if you need to handle longer texts that must fit a specific area of the image? You can achieve this by calculating text size and implementing text wrapping:


from PIL import Image, ImageDraw, ImageFont

# Load an image
image = Image.open('path/to/image.jpg')

# Establish the drawing context

draw = ImageDraw.Draw(image)

# Set the maximum width for the text
max_width = 100

# Define the font
font = ImageFont.truetype('arial.ttf', size=15)

# Define the text and its position
text = 'A long line of text that will need to be wrapped to fit within the specified max_width.'


(x, y) = (10, 10)

# Wrap the text

lines = []
line = ''
for word in text.split():
    # check the width of the line with the new word
    if draw.textsize(line + ' ' + word, font=font)[0] <= max_width:
        line += ' ' + word
    else:
        # line's width exceeds max_width, wrap it
        lines.append(line)
        line = word

# catch the last line if it's not empty
if line:
    lines.append(line)

# Render each line of text
for line in lines:
    draw.text((x, y), line.strip(), font=font)
    y += font.getsize(line)[1]  # move y to the next line

# Save the image
image.save('wrapped_text.jpg')

Here, text is split into words and lines are added one by one, making sure they don’t exceed the specified maximum width. Once the text is wrapped, each line is drawn on the image, and the vertical position is adjusted to prevent overlapping.

Using Advanced Font Properties

Outlined Text

Outlined text can make your text stand out more on complex backgrounds. Here’s how you can accomplish it with Pillow:


from PIL import Image, ImageDraw, ImageFont

# Load image
image = Image.open('path/to/image.jpg')

# Initialize drawing context

draw = ImageDraw.Draw(image)

# Define font and text properties
font_path = 'arial.ttf'
font_size = 50
font = ImageFont.truetype(font_path, size=font_size)

outline_color = 'black'
text_color = 'white'
text = 'Outlined Text'


(x, y) = (100, 100)

# Draw outline
for adj in range(-2, 3):
    # We create a shadow for each x, y offset
    draw.text((x + adj, y), text, font=font, fill=outline_color)
    draw.text((x, y + adj), text, font=font, fill=outline_color)

# Draw text

draw.text((x, y), text, fill=text_color, font=font)


# Save the image with outlined text
image.save('outlined_text.jpg')

This will draw a small outline around each letter of the text, which gives the outlined effect. Note that we draw the outline first and the actual text last, so it overlays on top of the outline.

Applying Transparency to Text

When adding text to images, sometimes transparent text can look more appealing and incorporate well into the design. This requires working with alpha values in an RGBA color tuple:


from PIL import Image, ImageDraw, ImageFont

# Load image
image = Image.open('path/to/image.jpg')

# Convert the image to RGBA (if not already in this mode) to handle transparency
image = image.convert('RGBA')

# Create a transparent overlay

overlay = Image.new('RGBA', image.size, (255,255,255,0))
draw = ImageDraw.Draw(overlay)

# Define font and text properties
font = ImageFont.truetype('arial.ttf', size=45)
text_color = (255, 255, 255, 128)  # White with half opacity

(x, y) = (50, 50)

# Draw text


draw.text((x, y), 'Transparent Text', fill=text_color, font=font)

# Alpha composite the overlay onto the image

image_alpha = Image.alpha_composite(image, overlay)

# Convert back to RGB and save image
image_rgb = image_alpha.convert('RGB')
image_rgb.save('transparent_text.jpg')

Conclusion

Through this tutorial, we’ve learned the steps for writing text to images using Pillow in a variety of ways. While the basics of adding text is simple, you can create more complex effects with advanced techniques. Experiment with Pillow’s comprehensive functionalities for more stylized options.