Pillow is the most popular and user-friendly library for image processing in Python. It is a "friendly fork" of the original Python Imaging Library (PIL) and has become the de facto standard for a wide range of image manipulation tasks. Pillow allows you to easily open, manipulate, and save various image file formats using simple and intuitive Python code.
It's an essential tool for developers in web development (for creating thumbnails or processing user-uploaded images), data science (for preparing images for machine learning models), and any application that requires programmatic image editing.
Key Concepts
- The Image Module: The core of the library is the Image module, which contains the functions to load images from files and create new images.
- Image Objects: When you open an image with Pillow, it creates an Image object. This object stores the image data and has methods (.resize(), .rotate(), etc.) that you can call to perform operations.
- Modes: Images have different modes, which define the type and depth of a pixel. The most common are:
- 'L' for grayscale (luminance).
- 'RGB' for true color images (Red, Green, Blue).
- 'RGBA' for true color with an alpha channel for transparency.
Code Examples
To run these examples, you first need to install Pillow: pip install Pillow
You will also need an image file. Let's assume you have an image named example.jpg in the same directory as your Python script.
1. Opening and Displaying an Image
This is the most basic operation. The .show() method opens the image in your system's default image viewer.
from PIL import Image
try:
# Open the image file
img = Image.open('example.jpg')
# Display the image
img.show()
# Print some basic attributes
print(f"Image Format: {img.format}")
print(f"Image Size: {img.size}") # (width, height)
print(f"Image Mode: {img.mode}")
except FileNotFoundError:
print("Error: The file 'example.jpg' was not found.")
print("Please make sure you have an image with that name in the same directory.")
2. Resizing an Image
Creating thumbnails or standardizing image sizes is a very common task. The .resize() method takes a tuple (width, height) as its argument.
from PIL import Image
try:
img = Image.open('example.jpg')
# Define the new size
new_size = (300, 300)
# Resize the image
resized_img = img.resize(new_size)
# Save the resized image to a new file
resized_img.save('example_resized.jpg')
print("Image resized and saved as 'example_resized.jpg'")
resized_img.show()
except FileNotFoundError:
print("Error: The file 'example.jpg' was not found.")
3. Cropping an Image
Cropping allows you to select a rectangular portion of an image. The .crop() method takes a 4-element tuple (left, upper, right, lower) representing the pixel coordinates of the box to crop.
from PIL import Image
try:
img = Image.open('example.jpg')
# Define the box to crop (left, upper, right, lower)
# This will crop a 200x200 box from the top-left corner
box = (0, 0, 200, 200)
# Crop the image
cropped_img = img.crop(box)
# Save and show the cropped image
cropped_img.save('example_cropped.jpg')
print("Image cropped and saved as 'example_cropped.jpg'")
cropped_img.show()
except FileNotFoundError:
print("Error: The file 'example.jpg' was not found.")
4. Rotating an Image
You can rotate an image by a specified number of degrees counter-clockwise.
from PIL import Image
try:
img = Image.open('example.jpg')
# Rotate the image by 90 degrees counter-clockwise
rotated_img = img.rotate(90)
# Save and show the rotated image
rotated_img.save('example_rotated.jpg')
print("Image rotated and saved as 'example_rotated.jpg'")
rotated_img.show()
except FileNotFoundError:
print("Error: The file 'example.jpg' was not found.")
5. Applying Filters
Pillow comes with the ImageFilter module, which contains several pre-defined filters you can apply.
from PIL import Image, ImageFilter
try:
img = Image.open('example.jpg')
# Apply a Gaussian blur filter
blurred_img = img.filter(ImageFilter.GaussianBlur(radius=5))
# Save and show the blurred image
blurred_img.save('example_blurred.jpg')
print("Image blurred and saved as 'example_blurred.jpg'")
blurred_img.show()
except FileNotFoundError:
print("Error: The file 'example.jpg' was not found.")
6. Adding Text to an Image
You can draw text directly onto an image using the ImageDraw module. This is useful for watermarking or annotating images.
from PIL import Image, ImageDraw, ImageFont
try:
img = Image.open('example.jpg')
# Create a drawing context
draw = ImageDraw.Draw(img)
# You may need to specify the path to a .ttf font file on your system
# If you don't have a specific font, Pillow may use a default one
try:
font = ImageFont.truetype("arial.ttf", 36)
except IOError:
print("Arial font not found, using default font.")
font = ImageFont.load_default()
# Define the text and position
text = "© Studylover 2025"
position = (10, 10) # (x, y) from top-left corner
# Draw the text on the image
draw.text(position, text, font=font, fill=(255, 255, 255)) # White text
# Save and show the watermarked image
img.save('example_watermarked.jpg')
print("Image watermarked and saved as 'example_watermarked.jpg'")
img.show()
except FileNotFoundError:
print("Error: The file 'example.jpg' was not found.")
7. Automated Image Processing Pipeline with Pillow
This Python script demonstrates a complete workflow for image manipulation using the Pillow library. It takes an input image and applies a series of common editing tasks in sequence, including resizing, cropping, rotating, and applying a sharpening filter. Finally, it adds a text watermark before saving the processed image as a new file, showcasing a practical pipeline for batch image processing.
# Import the necessary modules from the Pillow library
from PIL import Image, ImageDraw, ImageFont, ImageFilter
# --- Main Image Processing Function ---
def process_image(image_path):
"""
Opens an image and applies a series of manipulations:
resize, crop, rotate, filter, and add text.
"""
try:
# --- 1. Open the Image ---
# This is the starting point for all operations.
print(f"Opening image: {image_path}")
original_img = Image.open(image_path)
print(f"Original size: {original_img.size}")
# --- 2. Resize the Image (Creating a Thumbnail) ---
# We'll create a smaller version while maintaining the aspect ratio.
# This is useful for creating consistent image sizes.
thumb_size = (400, 400)
img = original_img.copy() # Work on a copy to keep the original
img.thumbnail(thumb_size)
print(f"Resized to fit within: {thumb_size}")
# --- 3. Crop the Image ---
# Let's crop the image to a square from its center.
w, h = img.size
left = (w - 250) / 2
top = (h - 250) / 2
right = (w + 250) / 2
bottom = (h + 250) / 2
img = img.crop((left, top, right, bottom))
print(f"Cropped to: {img.size}")
# --- 4. Rotate the Image ---
# Rotate the image slightly for a stylistic effect.
img = img.rotate(-5) # Rotate 5 degrees clockwise
print("Rotated by -5 degrees.")
# --- 5. Apply a Filter ---
# Apply a subtle sharpening filter to make details stand out.
img = img.filter(ImageFilter.SHARPEN)
print("Applied SHARPEN filter.")
# --- 6. Add Text (Watermark) ---
# Create a drawing context to draw on the image.
draw = ImageDraw.Draw(img)
# Load a font. If the specific font isn't found, it uses a default.
try:
# You might need to change "arial.ttf" to a font file on your system.
font = ImageFont.truetype("arial.ttf", 20)
except IOError:
print("Arial font not found, using default font.")
font = ImageFont.load_default()
# Define the text, position, and color.
text = "© Processed 2025"
text_position = (10, img.height - 30) # Position at bottom-left
text_color = (255, 255, 255) # White
# Draw the text on the image.
draw.text(text_position, text, font=font, fill=text_color)
print("Added watermark text.")
# --- 7. Save and Show the Final Image ---
final_image_path = 'example_processed.jpg'
img.save(final_image_path)
print(f"Successfully processed image and saved as '{final_image_path}'")
# Display the final result.
img.show()
except FileNotFoundError:
print(f"Error: The file '{image_path}' was not found.")
print("Please make sure you have an image with that name in the same directory.")
except Exception as e:
print(f"An error occurred: {e}")
# --- Run the processing function ---
# You need an image named 'example.jpg' for this script to work.
if __name__ == "__main__":
process_image('example.jpg')