Of course! This is a very common and powerful combination for working with images on Windows. Here’s a comprehensive guide covering what it is, why you'd use it, how to install it, and code examples from basic to advanced.

What is PIL and Pillow?
- PIL (Python Imaging Library): This was the original, go-to library for image manipulation in Python. Unfortunately, it's no longer maintained and doesn't support Python 3.
- Pillow: This is the modern, actively maintained, and friendly fork of PIL. If you find any documentation or tutorials mentioning "PIL", they are almost certainly referring to
Pillow. It's the de-facto standard for image processing in Python today.
When you install Pillow, you import it using the PIL namespace to maintain compatibility with old code. This is why you'll see from PIL import Image.
Why Use Pillow on Windows?
Pillow allows you to perform a vast range of image operations directly from your Python scripts. This is incredibly useful for automating tasks like:
- Resizing images for web pages or social media.
- Converting image formats (e.g., from
.pngto.jpg). - Cropping, rotating, and flipping images.
- Applying filters (blur, sharpen, etc.).
- Reading image metadata (EXIF data, dimensions, etc.).
- Creating thumbnails.
- Drawing shapes and text onto images.
Installation on Windows
The easiest way to install Python packages is using pip, Python's package installer.
Step 1: Open Command Prompt or PowerShell

- Press the Windows Key.
- Type
cmdorpowershelland press Enter.
Step 2: Install Pillow Run the following command in your terminal:
pip install Pillow
If you have multiple Python versions installed, you might need to be more specific, for example:
py -m pip install Pillow
This command ensures you're using the pip associated with your default Python installation.
Step 3: Verify the Installation You can quickly check if it was installed correctly by running a quick Python command:

python -c "from PIL import Image; print('Pillow version:', Image.__version__)"
If you see the Pillow version number printed, you're all set!
Basic Code Examples
Let's dive into some practical examples. You'll need a sample image to work with. Let's assume you have an image named my_photo.jpg in the same directory as your Python script.
Example 1: Opening, Displaying, and Getting Information
This is the "Hello, World!" of image processing.
from PIL import Image
try:
# Open an image file
img = Image.open("my_photo.jpg")
# Display some basic information about the image
print(f"Filename: {img.filename}")
print(f"Format: {img.format}")
print(f"Mode: {img.mode}") # e.g., 'RGB', 'L' (grayscale), 'RGBA'
print(f"Size: {img.size}") # A tuple (width, height) in pixels
print(f"Width: {img.width}")
print(f"Height: {img.height}")
# Show the image (this will open it in your default image viewer)
img.show()
except FileNotFoundError:
print("Error: The file 'my_photo.jpg' was not found.")
except Exception as e:
print(f"An error occurred: {e}")
Example 2: Resizing and Saving
This is one of the most common tasks. We'll create a thumbnail.
from PIL import Image
try:
img = Image.open("my_photo.jpg")
# Get the original size
original_width, original_height = img.size
print(f"Original size: {original_width}x{original_height}")
# Define the new size for the thumbnail (e.g., max 300px on the longest side)
# The thumbnail method preserves aspect ratio.
max_size = (300, 300)
img.thumbnail(max_size)
# Get the new size
new_width, new_height = img.size
print(f"New thumbnail size: {new_width}x{new_height}")
# Save the resized image
# You can save it as a different format or with a different quality
img.save("thumbnail.jpg", "JPEG", quality=85) # quality is for JPEGs
print("Thumbnail saved as 'thumbnail.jpg'")
except FileNotFoundError:
print("Error: The file 'my_photo.jpg' was not found.")
Example 3: Cropping an Image
The crop() method takes a 4-tuple (left, upper, right, lower).
from PIL import Image
try:
img = Image.open("my_photo.jpg")
# Define the crop box (left, upper, right, lower)
# This box will be 200 pixels from the left, 100 from the top,
# and 200 pixels wide, 150 pixels tall.
crop_area = (200, 100, 400, 250) # (left, upper, right, lower)
cropped_img = img.crop(crop_area)
# Save the cropped image
cropped_img.save("cropped_image.jpg")
print("Cropped image saved as 'cropped_image.jpg'")
except FileNotFoundError:
print("Error: The file 'my_photo.jpg' was not found.")
Example 4: Converting Image Formats
This is as simple as changing the file extension in the save() method.
from PIL import Image
try:
# Open a PNG image
img_png = Image.open("my_photo.png")
# Convert and save as a JPEG
# Note: JPEG doesn't support transparency, so if the PNG has an alpha channel,
# you might need to handle it. A simple way is to convert to RGB.
if img_png.mode == 'RGBA':
# Create a white background
background = Image.new('RGB', img_png.size, (255, 255, 255))
# Paste the image on the background, using the alpha channel as a mask
background.paste(img_png, mask=img_png.split()[3]) # 3 is the alpha channel
background.save("converted_image.jpg", "JPEG")
else:
img_png.save("converted_image.jpg", "JPEG")
print("Image converted and saved as 'converted_image.jpg'")
except FileNotFoundError:
print("Error: The file 'my_photo.png' was not found.")
Advanced Features: Working with Windows Paths
On Windows, file paths can sometimes be tricky due to backslashes (\). It's highly recommended to use raw strings (prefixed with r) for paths to avoid issues with escape characters.
Good Practice:
# Use a raw string for Windows paths image_path = r"C:\Users\YourUser\Pictures\my_photo.jpg" output_path = r"C:\Users\YourUser\Pictures\output.jpg" img = Image.open(image_path) # ... do something ... img.save(output_path)
Even Better Practice: Use the pathlib Module
The pathlib module provides an object-oriented way to handle filesystem paths and works seamlessly on Windows, macOS, and Linux.
from PIL import Image
from pathlib import Path
# Create Path objects
image_path = Path("C:/Users/YourUser/Pictures/my_photo.jpg")
output_path = Path("C:/Users/YourUser/Pictures/output.jpg")
# You can use / to join paths, which is very clean
output_dir = Path("C:/Users/YourUser/Pictures/processed_images")
final_output_path = output_dir / "final_thumb.jpg"
# Create the output directory if it doesn't exist
output_dir.mkdir(parents=True, exist_ok=True)
try:
img = Image.open(image_path)
img.thumbnail((300, 300))
img.save(final_output_path)
print(f"Image saved to {final_output_path}")
except FileNotFoundError:
print(f"Error: The file was not found at {image_path}")
Summary
| Task | Key Code Snippet |
|---|---|
| Install | pip install Pillow |
| Open Image | img = Image.open("path/to/image.jpg") |
| Get Info | img.size, img.format, img.mode |
| Resize (Thumbnail) | img.thumbnail((width, height)) |
| Crop | img.crop((left, top, right, bottom)) |
| Save | img.save("new_name.jpg", "JPEG") |
| Convert Format | img.save("new_name.png", "PNG") |
| Handle Paths | Use r"C:\path\to\file" or pathlib.Path |
Pillow is an essential tool for any Python developer working with images on Windows (or any other OS). Start with the basics, and you'll quickly find it indispensable for automating your image workflows.
