Image Effects How to Make a Low-Quality Image Look Better Understanding Lossless Image Compression How to Set Up Image Registration in Python 8 Different Image Processing Techniques You Can Use 4 Ways to Make an Image Larger without Losing Quality 3 Easy Ways to Eliminate Duplicate Images The Basics of Face Detection in Python How to Implement Multiple File Upload in PHP Like a Pro Creating Custom Image Cropping Interfaces in Android How to Create Simple Yet Effective PHP Overlay Understanding Real-Time Image Recognition How to add a shadow effect to an image with CSS How to crop an image in Flutter with Cloudinary How To Rotate an Image with Java Image Processing with Python Rotating an image with CSS Enhancing User Experience with a Responsive Image Slider Building a Python Image Recognition System Building an Interactive JavaScript Image Manipulation Tool Image Align Centering with HTML and CSS Efficient Image Cropping Techniques with Angular and Cloudinary Ultimate Guide to Photo Gallery on Android A Comprehensive Guide to Adding Text to Images on Android Mastering Background Changes in React Applications Comprehensive Guide on Changing Background on Android Devices Mastering Image Rotation in Java A Guide to Adding Text to Images with Python A Guide to Converting Images to Grayscale with Python Introduction Creating an Image Overlay with JavaScript Rotating an Image in Python Creating a Dynamic Photo Gallery with jQuery Creating An Interactive Photo Gallery Using JavaScript Mastering Overlay in Android Mastering Angular Overlay: A Comprehensive Guide Comprehensive Guide to Overlay in Flutter Mastering Overlay React for Responsive Design Solutions Create a Blurred Image with PHP: A Comprehensive Guide Guide to Using Blur Image in Flutter Mastering Blur Image in React Native Mastering Image Blurring in Python Mastering the Art of Image Blurring Mastering the Art of Image Blurring in Java The Ultimate Guide to Blurring Images on Android Understanding and Implementing Blur Image in JQuery An Extensive Walkthrough of Blurring Images with JavaScript How to Use HTML, CSS, and JavaScript to Make an Image Slider HTML Image Tag How to Crop GIFs? How to Align Images with CSS Ken Burns Effect – Complete Guide and How to Apply It Cartoonify – Complete Guide on Cartoonify Image Effect Mastering Web Aesthetics: A Comprehensive Guide to Gradient Fades Sepia Effect: The Ultimate Guide to the Sepia Photo Effect What is Vignette? Guide to Vignette Image Editing Pixelate – The Ultimate Guide to the Pixelation Effect How to Outline an Image: Enhancing Visual Appeal and Depth Make Your Photos Pop with Image Effects Upscale Image – Developers guide to AI-driven image upscaling Image Manipulation: History, Concepts and a Complete Guide A Full Guide to Object-aware Cropping Simplify Your Life with Automatic Image Tagging How To Resize Images In WordPress How To Create a Progress Bar For Asset Uploads Animated GIFs – What They Are And How To Create Them How To Automatically Improve Image Resolution AI Drop Shadow Get Image Dimensions From URLs Automatically Add Sepia Effect To Images Automatically Make an Image a Cartoon Automatically Add Blur Faces Effect To Images Automatically Add Background Removal Effect to an Image How to Resize an Image with React How to Easily Resize an Image with React Native

A Guide to Adding Text to Images with Python

text to images python

Enhancing images with information in the form of text is an effective way to improve communication in today’s digital world. Whether you’re a content creator making social media posts, banners, and business flyers or a developer building cool projects like a meme generator, your ability to use texts together with images can significantly liven up your projects.

In this guide, we’ll explore how to add text to images using Pillow, a powerful image processing library for Python. We’ll also explore how to achieve the same thing using Cloudinary, a cloud-based image and video management platform. Let’s get started!

In this article:

Prerequisites

Before you proceed, we assume that you’re equipped with the following:

  • A Python installation on your computer. If you don’t, visit the official Python website at python.org to download the installer for your OS.
  • A solid background in Python

text to images python

Adding Text to Images with Pillow

Pillow is a fork of Python Imaging Library, a free and open-source image manipulation and processing library with support for manipulating and working with many image file formats.

Step 1 – Setting up the Project

Like any other Python project, starting a new project in a virtual environment is usually a good idea. First of all, create a new directory for the project and run the code below to create a virtual environment:

python3 -m venv env
source env/bin/activate

Step 2 – Installing Necessary Libraries

The major library we’ll be using in this part of the tutorial is Pillow. If you haven’t already installed it, you can do so using pip:

pip install Pillow

Step 3 – Import Pillow and Load the Image

Next, create a main.py file in the project and add the following code to it:

from PIL import Image, ImageDraw, ImageFont

# Load the image
image = Image.open("wallpaper.jpg")

# Create a drawing context
draw = ImageDraw.Draw(image)

The ImageDraw.Draw module from Pillow lets us create a drawing context on the opened image. Now, we can use the draw object to perform various drawing operations on the image, such as drawing lines, shapes, and text.

NOTE: You’ll need to upload an image in the root directory that you want to render the text on. In the code above, we used an image file named wallpaper.jpg.

Step 4 – Defining the Text and Position

# ...
# Define the text properties
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 36)
text = "Hello, World!"
position = (50, 50)

# Add text to the image
draw.text(position, text, font=font)

# Save or display the modified image
image.save("output.jpg")

The ImageFont.truetype module loads TrueType and OpenType font types from a file and lets you specify a font size. The draw.text method renders text on the image. Its parameters define the position, text, and font for rendering characters on the image.

NOTE: To prevent errors and for the text to render correctly, we have to specify an absolute path to the font we want to use in rendering the text. In our case, we used a system font located on our computer. Alternatively, you can copy the font file or download a font from the internet and place it in the project–just make sure you link to the font properly.

And here’s the output of the generated image:

text to images python

Step 5 – Modifying the Text Styles

If you look at the output image above, you’ll notice that the rendered text looks bland. We can get creative and edit the image further to our taste by adding CSS-like styles.

For example, to center the rendered text, we can simply modify our code to the following:

from PIL import Image, ImageDraw, ImageFont

# Load the image
image = Image.open("wallpaper.jpg")

# Create a drawing context
draw = ImageDraw.Draw(image)

# Define the text properties
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 36)
text = "Hello, World!"
text_color = (255, 255, 255)

# Calculate the position to center the text
text_length = draw.textlength(text, font)
x = (image.width - text_length) / 2
y = image.height / 2

# Add text to the image
draw.text((x, y), text, fill=text_color, font=font)

# Save or display the modified image
image.save("output.jpg")

Now we can see the text rendered in the center of the image as follows:

text to images python

Adding Text to Images with Cloudinary

Pillow is great, really. But it might be a nightmare for beginners with no advanced Python expertise. However, adding text to images with Cloudinary is much easier than using other solutions like Pillow.

For instance, Cloudinary provides many battery-included features like adding dynamic text to any image on the fly and using any of the hundreds of Google Fonts available. You can even use your own custom font, apply a myriad of text styling options, and explore many other customizations you can play with!

In this section, we’ll walk you through how you can use Cloudinary to add text to images.

Step 1 – Setting up the Application

Create a new directory for the project and initialize a virtual environment. Next, run the following command to install the necessary packages for the project:

python3 -m pip install fastapi cloudinary python-multipart 
pydantic-settings python-dotenv uvicorn[standard]

Here’s a description of the packages we are installing.

  • FastAPI: A Python framework for creating web servers and APIs.
  • python-multipart: A Python library for handling multipart/form-data POST requests.
  • python-dotenv: Loads key-value pairs from a .env file and make them available as environment variables.
  • pydantic-settings: A Python library that provides a way to manage application settings and configurations using Pydantic models.
  • Cloudinary: A cloud-based service offering a complete solution for managing images and videos. It provides functions including uploading, storing, manipulating, optimizing, and delivering images.
  • Uvicorn: An ASGI web server implementation in Python.

Step 2 – Creating the Server

Create a file named main.py in the root directory and add the code below to it to create the application server:

from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
    return "App is working!"

Run uvicorn main:app --reload to start up the server.

Step 3 – Adding Environment Variables

In order to gain access to the features of Cloudinary using the Python SDK, we need to provide our environment credentials so we can access the service programmatically. You’ll find your own environment credentials in your Cloudinary dashboard.

Next, create a .env file in the root of the project and add your credentials as follows:

CLOUDINARY_API_KEY =
 <YOUR_CLPOUDINARY_API_KEY>CLOUDINARY_CLOUD_NAME =
 <YOUR_CLOUDINARY_CLOUD_NAME>CLOUDINARY_API_SECRET =
 <YOUR_CLOUDINARY_API_SECRET>

Step 4 – Writing the Code

In main.py, change the entire code to the following:

# Import the necessary packages
from fastapi import FastAPI
from fastapi import FastAPI, File, UploadFile
from pydantic_settings import BaseSettings
import cloudinary
import os

app = FastAPI()

# Configure environment variables
class Settings(BaseSettings):
    CLOUDINARY_CLOUD_NAME: str
    CLOUDINARY_API_KEY: int
    CLOUDINARY_API_SECRET: str
    class Config:
        env_file = ".env"

settings = Settings()

# Load in the environment variables
config = cloudinary.config(cloud_name = settings.CLOUDINARY_CLOUD_NAME, api_key = settings.CLOUDINARY_API_KEY, api_secret = settings.CLOUDINARY_API_SECRET)

import cloudinary.uploader
import cloudinary.api

# Function to upload the image to Cloudinary and apply the text overlay
async def cloudinary_upload(file):
    imageURL =  cloudinary.uploader.upload(file, transformation=[
  {'color': "white", 'overlay': {'font_family': "Arial", 'font_size': 80, 'text': "Hello, Cloudinary!"}},
  {'flags': "layer_apply"}
  ])
    return imageURL
     
# Endpoint to upload the file to the server    
@app.post("/upload")
async def create_image(image: UploadFile = File(...)):
    os.makedirs("images", exist_ok=True)
	# Save the uploaded image to disk
    file_location = f"images/{image.filename}"
    with open(file_location, "wb+") as file_object:
        file_object.write(image.file.read())

    result = await cloudinary_upload(file_location)

	# Get the URL of the transformed image
    imageURL = result["secure_url"]

    return f"Link to the image with text overlay: {imageURL}"

@app.get("/")
async def root():
    return "App is working!"

Step 5 – Trying It Out

Now, let’s use the Postman extension in VS Code to try out our code. To do this, set your “requests” parameters in the Postman extension as shown below:

text to images python

Here’s the image output when we paste the generated link into the browser:

text to images python

The text was rendered, yay! But wait, that’s not how we expected it to turn out – the comma in the text was rendered as %2C. Text strings containing special characters need to be escaped before we can add them as layers on images.

Let’s modify our code to fix that.

# ...import urllib.parse
# ...def escape_special_characters(text):
    special_characters = [
    '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
    '-', '_', '=', '+', '\\\\', '|', '{', '}', ';', ':', '/', '?', '.', '>']
# Escape each special character in the text    
for char in special_characters:
        if char in text:
            text = text.replace(char, urllib.parse.quote(char))
    return text
async def cloudinary_upload(file):
    input_text = "Hello, Cloudinary!"    text  =  escape_special_characters(input_text)
    imageURL =  cloudinary.uploader.upload(file, transformation=[
  {'color': "white", 'overlay': {'font_family': "Arial", 'font_size': 80, 'text': text}},
  {'flags': "layer_apply"}
  ])
    return imageURL
# ...

In the code above, we defined an escape_special_characters function that escapes special characters in the text we want to add to the image. The function uses the urllib.parse.quote() function in the urllib.parse Python module to convert any special character added in the text to its UTF-8 encoded value.

Now, we can be sure that Cloudinary will render the text correctly.

Wrapping Up

In this article, we showed you how to add text to images using Pillow, a popular image manipulation tool built with Python. We also walked you through how you can accomplish the same thing using Cloudinary, a cloud-based media management platform.

To learn more about adding text to images, please check out adding layers to images and text transformation reference in the Cloudinary documentation.

Optimize, transform, and manage your media assets like a pro with Cloudinary. Sign up for free today!

QUICK TIPS
Colby Fayock
Cloudinary Logo Colby Fayock

In my experience, here are tips that can help you better implement and optimize text overlays on images using Python and Cloudinary:

  1. Use layered transformations for advanced compositions
    When adding multiple text elements or combining text with other overlays, use Cloudinary’s layered transformations. This approach gives you fine control over positioning, styling, and visibility, ensuring each layer is applied accurately.
  2. Implement dynamic text generation for personalized content
    Utilize Python’s dynamic string formatting (f-strings or format() method) to generate personalized text for each image. For example, in e-commerce apps, you can create dynamic price labels, product descriptions, or promotional text based on user data or external content feeds.
  3. Leverage Google Fonts for stylistic flexibility
    Cloudinary supports hundreds of Google Fonts, allowing you to easily change fonts using the font_family parameter (e.g., "font_family": "Roboto"). Experiment with different fonts to match the style and tone of your image content without the need for local font files.
  4. Use Pillow’s textbbox for precise text placement
    When using Pillow, use the textbbox() method to get the bounding box dimensions of text. This helps in accurately placing text in relation to other elements in the image, ensuring that text does not overlap with key visual components.
  5. Incorporate shadow and outline effects for text visibility
    For better text visibility over complex backgrounds, use the stroke_width and stroke_fill parameters in Pillow’s draw.text() method or Cloudinary’s border option. Adding a subtle shadow or outline around text improves legibility, especially for images with varied colors.
  6. Optimize text-based images with Cloudinary’s q_auto
    When generating text-heavy images (e.g., banners or posters), use Cloudinary’s q_auto parameter to automatically adjust the quality. This minimizes file size without compromising text sharpness, ensuring optimal delivery across devices.
  7. Use text auto-resizing for adaptive content
    For dynamic text that varies in length (e.g., user comments or product descriptions), implement a text auto-resizing function using ImageFont in Pillow. This dynamically adjusts the font size based on the available space, preventing text from overflowing or getting cut off.
  8. Implement real-time previews for better UX
    When building interactive tools (e.g., meme generators or graphic editors), integrate real-time text previews using asyncio or Flask’s SSE (Server-Sent Events) to stream updates as users type. This helps users fine-tune the text before applying it to the final image.
  9. Use Cloudinary’s gravity parameter for intelligent positioning
    When adding text to images, use the gravity parameter (e.g., gravity: "north") to position text based on the image’s content or focal points. This ensures that the text appears in visually appropriate areas without manual adjustments, especially for images with diverse subjects.
  10. Optimize text rendering with Cloudinary’s fetch_format:auto
    Use Cloudinary’s fetch_format:auto transformation when delivering images with text overlays to automatically convert the output to efficient formats like WebP or AVIF. This reduces bandwidth usage and ensures high-quality rendering across different browsers and devices.

These advanced tips will help you create visually appealing and optimized text overlays in your Python applications, leveraging both Pillow and Cloudinary’s powerful image manipulation capabilities.

Last updated: Oct 2, 2024