Python Tutorial: Image Manipulation with Pillow
Based on Corey Schafer's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.
Install Pillow using the OS-specific documentation steps, and be ready to install additional dependencies (e.g., via Homebrew on macOS) before running `pip install pillow`.
Briefing
Pillow turns Python into a practical image-processing tool, letting developers batch-display, convert, resize, and transform images without manual editing. The core payoff is automation: instead of resizing every upload by hand, a script can generate the exact derivative files a website needs—different formats, thumbnail sizes, and gallery-ready versions—directly from a folder of originals.
Getting started is straightforward but not entirely “pip-only.” After installing Pillow (via the Pillow documentation’s OS-specific instructions), the workflow may require additional external libraries—on macOS, the tutorial uses Homebrew to install those dependencies—then verifies the install by importing Image from PIL (e.g., `from PIL import Image`). Once the import works, the tutorial demonstrates the basic pattern: open an image file into an Image object, perform an operation, and save the result.
The first concrete example is format conversion. An image is opened with `Image.open(...)`, displayed using `image.show()`, then saved as a different extension using `image.save(...)`—switching from `pup one.jpeg` to `pup one.png`. After confirming the new file exists and opens correctly, the script deletes the PNG to keep the workspace clean.
Batch processing is where Pillow becomes especially valuable. The tutorial loops through all files in the current directory using `os.listdir('.')`, filters for JPEGs by checking filename endings, and for each match opens the image, splits the base name and extension with `os.path.splitext`, and saves a converted PNG into a dedicated output folder (e.g., `pngs/`). This produces a parallel set of images with consistent naming.
Next comes resizing for web use while preserving aspect ratio. The script defines a target size as a tuple (e.g., `(300, 300)`), creates an output directory for that size (e.g., `300/`), and applies `image.thumbnail(size)` before saving. Filenames are updated to include the size suffix (e.g., `originalname_300.jpeg`), making it easy to map derivatives back to originals. The same logic scales to multiple requirements: adding a 700-pixel variant is done by duplicating the step with a new size and output folder, producing both 300 and 700 versions quickly.
Finally, the tutorial broadens the toolkit beyond resizing and format changes. It demonstrates single-image transformations: rotating an image by 90 degrees with `image.rotate(90)`, converting to black-and-white using `image.convert(mode='L')`, and applying a Gaussian blur via `ImageFilter.GaussianBlur(radius=...)`. It highlights that blur strength depends on parameters (default blur is subtle; increasing the radius to around 15 makes the effect clearly visible).
Overall, Pillow is presented as a workflow enabler for image pipelines—especially for websites—where consistent derivative images (thumbnails, galleries, and resized formats) can be generated automatically from uploaded files using a small set of repeatable operations and the official documentation for parameter values.
Cornell Notes
Pillow lets Python scripts open images, transform them, and write new files—ideal for automating the repetitive work of preparing images for websites. After installing Pillow (and any required OS dependencies), images are loaded with `Image.open`, previewed with `image.show`, and saved with `image.save` in a chosen format. Batch conversion and resizing use `os.listdir` to iterate through files, filter by extension, and then apply operations like `image.thumbnail((w, h))` while keeping aspect ratio. The same approach scales to multiple sizes (e.g., 300 and 700) by running the resize-and-save step into different output folders. Additional transformations include rotation, black-and-white conversion, and Gaussian blur using `ImageFilter.GaussianBlur` with adjustable radius.
What is the basic Pillow workflow for changing an image file?
How does the tutorial batch-process multiple images in one run?
How does resizing avoid squishing images?
How can the script generate multiple thumbnail sizes efficiently?
What other image transformations are demonstrated besides resizing and format conversion?
Review Questions
- When converting a batch of JPEGs to PNGs, why is `os.path.splitext` useful for naming output files?
- What’s the difference between using `image.thumbnail((w, h))` and saving a resized image that forces exact dimensions?
- Which Pillow methods and parameters are used to rotate, convert to black-and-white, and apply Gaussian blur?
Key Points
- 1
Install Pillow using the OS-specific documentation steps, and be ready to install additional dependencies (e.g., via Homebrew on macOS) before running `pip install pillow`.
- 2
Use `from PIL import Image` to create an Image object with `Image.open(...)`, then preview with `image.show()` to confirm the file is loaded correctly.
- 3
Convert formats by saving the same Image object with a different extension using `image.save('name.ext')` (e.g., JPEG to PNG).
- 4
Batch operations can be automated by looping through directory contents with `os.listdir('.')` and filtering filenames by extension.
- 5
Preserve aspect ratio during resizing by using `image.thumbnail((max_w, max_h))` rather than forcing exact dimensions.
- 6
Generate multiple derivative sizes by running the same thumbnail-and-save step for each target size into separate output folders (e.g., `300/` and `700/`).
- 7
Use Pillow transformations like `rotate`, `convert(mode='L')`, and `ImageFilter.GaussianBlur(radius=...)` to create rotated, black-and-white, and blurred variants.