How to Modify Images using Pillow

5/5 - (4 votes)

Problem Formulation and Solution Overview

This article will show you how to use the Pillow Library in Python to modify and manipulate images.

To make it more interesting, we have the following running scenario:

Creative Prints is an online store accepting images from Photographers wishing to sell their art. The Manager would like you to modify all pictures by applying the methods outlined below and has provided one (1) sample image to work with.

To follow along, create two folders inside the current working directory: uploaded_imgs and updated_imgs.

Then, copy the above file to the uploaded_imgs directory by right-mouse clicking and saving this image as PL_13845_127654_red_train.png.

Filename Breakdown

PL or PPPhoto Landscape (PL), or Photo Portrait (PP)
13845Photographer ID (always 5 numbers)
127654Picture ID (always 6 numbers)

πŸ’¬ Question: How would we write code to apply filters to these images using the Pillow Library?

We can accomplish this task by applying of the following options to the image:

  • Method 1: Resize Image
  • Method 2: Sharpen Image
  • Method 3: Add Transparent Logo to Image
  • Method 4: Save Image
  • Bonus: Putting it Together

Before moving forward, please ensure the Pillow library is installed. Click here if you require instructions.

Then, add the following code to the top of each script. This snippet will allow the code in this article to run error-free.

from PIL import Image, ImageEnhance

After importing the Pillow library, this library is referenced by calling the shortcode (PIL).

Method 1: Resize Image

For this example, all uploaded images are re-sized to accommodate the website requirements. For Landscape images, 350×200, and for Portrait images 200×350.

img_main ='uploaded_imgs\PL_13845_127654.png')
img_resized = img_main.resize((350, 200))

The above code opens an image recently submitted by Photographer 13485 (ID). If successful, an image object returns and saves to img_main.

If output to the terminal, the object displays the image mode (RGBA), the image’s original size (787×403), and the object’s location in memory.

<PIL.PngImagePlugin.PngImageFile image mode=RGBA size=787x403 at 0x15EE1A84910>

Then, the highlighted line resizes the image indicated above for Landscape images to 350 pixels wide x 200 pixels high. The results save to img_resized.

Next, opens an image viewer on the computer to display the results.

The Ultimate Guide to Slicing in Python

Method 2: Apply Sharpness

For this example, the currently open image file has the sharpness filter applied to enhance the image.

img_sharp = img_resized.copy()
sharpness = ImageEnhance.Sharpness(img_sharp)

The above code copies the resized image created in Method 1. This creates an object similar to above and the results save to img_sharp.

The next line create a sharpness object. This object offers the ability to apply the sharpness filter to the image in question and saves to sharpness. If output to the terminal it would appear similar to below.

<PIL.ImageEnhance.Sharpness object at 0x000001AE3F74B520>

On the line below, a sharpness of 1.5 is applied to the stated image (img_sharp)

Next, opens an image viewer on the computer to display the results.

Method 3: Apply Logo to Image

This example applies the Creative Prints logo to all uploaded images and places this in the bottom left-hand corner. Download the image below and move it into the uploaded_imgs folder before continuing.

cp_logo ='updated_imgs\cp_logo_trans.png')
img_logo = img_sharp.copy()

logo_pos = (3, (img_logo.height-cp_logo.height-3))
img_logo.paste(cp_logo, logo_pos, cp_logo)

The above code opens the Creative Prints transparent logo and saves this to cp_logo. Then, a copy of the image created above saves to img_logo.

Next, the Creative Prints Logo placement on the original picture is determined and saves to logo_pos.

The following line pastes the Creative Prints logo on to the original train image at the position determined above.

Next, opens an image viewer on the computer to display the results.

Method 4: Save Updated Image

For this example, the code saves the updated image to the updated_imgs folder

fname = img_main.filename[14:-4] + '_cp' + img_main.filename[-4:]'updated_imgs\{fname}')

In Method 1, when the image was original opened, it was assigned to img_main. Even though changes have been made throughout this article, in order to retrieve the filename, the code needs to reference this.

As you can see, slicing has been used to strip the existing folder name from the file. Add a _cp reference indicating that Creative Prints has processed this image, and adds back in the original file extension.


This processed image saves to the updated_imgs folder.

Putting it Together!

This section streamlines the above methods as much as possible to make it a cleaner, more efficient solution.

See if you can spot the differences!

from PIL import Image, ImageEnhance
import os

directory = os.fsencode('uploaded_imgs')
for file in os.listdir(directory):
    filename = os.fsdecode(file)

    if filename.startswith('PL'):
        img_main ='uploaded_imgs\\{filename}').resize((350, 200))
        img_main ='uploaded_imgs\\{filename}').resize((200, 350))

    img_main = ImageEnhance.Sharpness(img_main).enhance(1.5)

    cp_logo ='updated_imgs\cp_logo_trans.png')
    img_main.paste(cp_logo, (3, (img_main.height-cp_logo.height-3)), cp_logo)'updated_imgs\{filename[0:-4]}_cp{filename[-4:]}')
🌟Finxter Challenge!
Add new images to the uploaded_imgs folder with both Portrait and Landscape orientations and add code to remove the photos from this folder once they have been processed.


This article has provided a few ways images can be manipulated. However, the Pillow Library has many more options available! May we suggest that you review the capabilities of this great library?

Good Luck & Happy Coding!

Programmer Humor – Blockchain

“Blockchains are like grappling hooks, in that it’s extremely cool when you encounter a problem for which they’re the right solution, but it happens way too rarely in real life.” source xkcd