1. Automating Batch Image Processing
Batch processing of images allows you to apply the same actions to a large number of files, saving time and effort. For example, if you have a folder full of images that need resizing or a watermark added, Pillow lets you create one script that applies the operations to all the images.
Resizing All Images in a Folder
In this example, we will resize all images in the input_images folder and save the results to the output_images folder.
import os
from PIL import Image
input_folder = "input_images/"
output_folder = "output_images/"
new_size = (800, 800)
# Make sure the folder for saving the images exists
os.makedirs(output_folder, exist_ok=True)
# Loop through each file in the input_folder
for filename in os.listdir(input_folder):
if filename.endswith((".jpg", ".jpeg", ".png")):
image_path = os.path.join(input_folder, filename)
# Open the image and resize it
with Image.open(image_path) as img:
resized_img = img.resize(new_size)
output_path = os.path.join(output_folder, filename)
# Save the image
resized_img.save(output_path)
print(f"Image {filename} successfully resized and saved.")
This script:
- Loads all files from the
input_imagesfolder. - Resizes each image to 800x800 pixels.
- Saves the resized images to the
output_imagesfolder.
Adding a Watermark to Images
Adding a watermark to all images in a folder is easily automated. In this example, a text watermark is added to the bottom-right corner of each image.
from PIL import ImageDraw, ImageFont
input_folder = "input_images/"
output_folder = "watermarked_images/"
watermark_text = "© My Company"
# Make sure the folder for saving the images exists
os.makedirs(output_folder, exist_ok=True)
for filename in os.listdir(input_folder):
if filename.endswith((".jpg", ".jpeg", ".png")):
image_path = os.path.join(input_folder, filename)
# Open the image and create a drawing object
with Image.open(image_path) as img:
draw = ImageDraw.Draw(img)
width, height = img.size
font = ImageFont.truetype("arial.ttf", 24)
# Position for the watermark
text_width, text_height = draw.textsize(watermark_text, font=font)
x = width - text_width - 10
y = height - text_height - 10
# Add the watermark
draw.text((x, y), watermark_text, font=font, fill=(255, 255, 255, 128))
output_path = os.path.join(output_folder, filename)
img.save(output_path)
print(f"Watermark added to image {filename}.")
This script:
- Loads all images from
input_images. - Adds a text watermark to the bottom-right corner of each image.
- Saves the results to
watermarked_images.
Converting Images to PNG Format
Converting all images to a single format is also easily automated. In this example, we convert all images in the folder to PNG format.
input_folder = "input_images/"
output_folder = "png_images/"
# Make sure the folder for saving the images exists
os.makedirs(output_folder, exist_ok=True)
for filename in os.listdir(input_folder):
if filename.endswith((".jpg", ".jpeg", ".bmp", ".tiff")):
image_path = os.path.join(input_folder, filename)
# Open and convert image to PNG
with Image.open(image_path) as img:
base_filename = os.path.splitext(filename)[0]
output_path = os.path.join(output_folder, f"{base_filename}.png")
img.save(output_path, "PNG")
print(f"Image {filename} successfully converted to PNG.")
This script converts images from formats like JPEG, BMP, or TIFF to PNG, saving them in the png_images folder.
2. Working with GIF Animations
GIF animations are sequences of images displayed in order to create a motion effect. Using Pillow, you can create and edit GIF animations, add or modify frames, and control animation speed.
Creating a Simple GIF Animation
To create a GIF animation, you need to prepare several images (frames) that will be displayed sequentially. In this example, we create a GIF from images in the frames folder.
# List of images for the animation
frames_folder = "frames/"
frames = []
for filename in sorted(os.listdir(frames_folder)):
if filename.endswith((".png", ".jpg")):
frame_path = os.path.join(frames_folder, filename)
frame = Image.open(frame_path)
frames.append(frame)
# Save frames into a GIF animation
frames[0].save("animation.gif", save_all=True, append_images=frames[1:], duration=100, loop=0)
This code:
- Loads images from the
framesfolder and adds them to theframeslist. - Creates a GIF animation from the frames.
- The parameter
duration=100specifies the display time for each frame in milliseconds, andloop=0sets the playback to loop infinitely.
Changing the Speed of a GIF Animation
To change the speed of the animation, simply adjust the duration parameter.
# Create an animation with increased speed
frames[0].save("fast_animation.gif", save_all=True, append_images=frames[1:], duration=50, loop=0)
In this example, duration=50 speeds up the GIF playback by twice.
Adding New Frames to an Existing GIF
You can also open an existing GIF, add new frames to it, and save the updated animation.
# Open an existing GIF
with Image.open("existing_animation.gif") as gif:
frames = [frame.copy() for frame in ImageSequence.Iterator(gif)]
# Add a new frame
new_frame = Image.open("new_frame.png")
frames.append(new_frame)
# Save the updated animation
frames[0].save("updated_animation.gif", save_all=True, append_images=frames[1:], duration=100, loop=0)
This code adds a new frame new_frame.png to the end of the animation.
Extracting Frames from a GIF Animation
Sometimes you need to split a GIF animation into individual frames. Pillow allows you to extract and save each frame separately.
from PIL import ImageSequence
# Open a GIF animation and extract frames
with Image.open("animation.gif") as gif:
for i, frame in enumerate(ImageSequence.Iterator(gif)):
frame.save(f"frame_{i}.png")
This code saves each frame from the animation as a separate PNG image.
Example of Full Workflow with GIF Animations and Batch Processing
To wrap up, here’s an example combining batch processing automation and working with GIFs. We create an animation from all images in a folder, resizing each frame before adding it.
# Load images, resize them, and create a GIF
input_folder = "input_images/"
frames = []
new_size = (400, 400)
for filename in sorted(os.listdir(input_folder)):
if filename.endswith((".jpg", ".jpeg", ".png")):
image_path = os.path.join(input_folder, filename)
with Image.open(image_path) as img:
resized_frame = img.resize(new_size)
frames.append(resized_frame)
GO TO FULL VERSION