Inspecting Image Attributes in Pillow
Learn how to open images with Pillow and inspect size, format, mode, metadata, palettes, and frame counts with practical Python examples.
What you inspect in a Pillow image
Pillow is a Python library for opening, inspecting, transforming, and saving image files. When you open an image, Pillow returns an Image object. This object represents the image and provides operations and properties related to it.
An instance attribute is a value attached to an object. For example, img.size describes an image's dimensions, while img.mode describes how its pixels are represented.
Inspecting attributes only reads information. It does not modify the image pixels or save a new file. Operations such as resizing, cropping, conversion, and saving are separate steps.
Install Pillow and open an image
Install Pillow in the Python environment used by your script:
python -m pip install Pillow
Import the Image module from Pillow, then pass an image path to Image.open():
from PIL import Image
img = Image.open("photo.jpg")
Image.open() identifies the source file and makes information about it available. Pillow may load pixel data lazily, meaning that all pixel data might not be read until an operation needs it. A context manager is usually the safest way to manage the file resource:
from PIL import Image
with Image.open("photo.jpg") as img:
print(img.size)
print(img.format)
print(img.mode)
Inside the with block, img is the Pillow Image object. When the block ends, Pillow closes the associated image resource.
Read the image size
The size attribute is a two-item Python tuple containing the image dimensions in pixels. Its order is (width, height), not (height, width).
from PIL import Image
with Image.open("photo.jpg") as img:
print(img.size)
For an image 1920 pixels wide and 1080 pixels tall, the output is:
(1920, 1080)
You can unpack the tuple into separate variables:
from PIL import Image
with Image.open("photo.jpg") as img:
width, height = img.size
print(f"Width: {width}px")
print(f"Height: {height}px")
Width is the horizontal pixel count. Height is the vertical pixel count. These values are useful when validating uploaded images, choosing crop bounds, checking minimum dimensions, and calculating proportional resize dimensions.
Read the source file format
The format attribute identifies the file format Pillow recognized when it opened the source file. Common values include JPEG, PNG, GIF, WEBP, TIFF, and BMP.
from PIL import Image
with Image.open("photo.jpg") as img:
print(img.format)
JPEG
The detected format is more trustworthy than a filename extension alone. A file can be renamed from .png to .jpg without changing its encoded contents, so use img.format when making validation decisions.
The format is associated with the file that was opened. A newly created image, or an image produced by some transformations, may have format set to None. If the source format matters, inspect it immediately after Image.open(). When saving a generated image, specify the desired output format explicitly.
Read the pixel mode
The mode attribute describes the image's pixel or color representation. It tells you how many channels or values are used for each pixel and can affect which operations and output formats are compatible.
from PIL import Image
with Image.open("photo.jpg") as img:
print(img.mode)
RGB
Common Pillow modes
RGB has three color channels: red, green, and blue. RGBA adds an alpha channel, which stores opacity or transparency. An alpha value can indicate that a pixel is fully opaque, partly transparent, or fully transparent.
This difference matters when saving. JPEG does not support an alpha channel, so an RGBA image generally must be converted or composited onto a background before it is saved as JPEG.
Print a clear attribute report
Labels make command-line output easier to understand:
from PIL import Image
with Image.open("photo.jpg") as img:
print("Size:", img.size)
print("Format:", img.format)
print("Mode:", img.mode)
Representative output for a typical JPEG with RGB pixels might be:
Size: (1920, 1080)
Format: JPEG
Mode: RGB
A concise f-string report is useful when you want one formatted line:
from PIL import Image
with Image.open("photo.jpg") as img:
width, height = img.size
report = f"{width}x{height}px | format={img.format} | mode={img.mode}"
print(report)
1920x1080px | format=JPEG | mode=RGB
Additional useful Image attributes
In addition to size, format, and mode, Pillow Image objects expose other useful properties:
img.width and img.height provide direct access to the two dimensions:
from PIL import Image
with Image.open("photo.jpg") as img:
if img.width >= 800 and img.height >= 600:
print("Large enough")
img.info is a dictionary of available file-specific metadata. Metadata is supplementary information stored with an image, such as DPI, EXIF-related values, color profiles, or text fields. Its contents depend on the source file and its format. Do not assume that every image contains EXIF data, transparency information, an ICC profile, or any other particular field.
from PIL import Image
with Image.open("photo.jpg") as img:
print("Format:", img.format)
print("Metadata:", img.info)
print("Frames:", getattr(img, "n_frames", 1))
Palette data is especially relevant to P-mode images. The n_frames attribute is useful for formats that may contain animation or multiple pages, but a regular still image usually has one frame. Optional attributes and metadata can vary by format and source file.
Use attributes to validate an image
A practical inspection workflow is:
- Open the source image.
- Read the properties relevant to your requirements.
- Decide whether the image is valid or requires processing.
- Only then convert, resize, crop, or save it.
- Use a context manager when the image resource should be closed after inspection.
For example, an upload pipeline can check the recognized format and minimum dimensions before processing:
from PIL import Image
with Image.open("upload.png") as img:
if img.format not in {"JPEG", "PNG", "WEBP"}:
raise ValueError("Unsupported image format")
if img.width < 800 or img.height < 600:
raise ValueError("Image must be at least 800 by 600 pixels")
print("Image is acceptable")
Checking attributes first avoids performing unnecessary transformations on files that do not meet your rules. For more advanced upload checks, combine this inspection with safe file handling and format-specific validation.
Handle transparency before saving as JPEG
If an image has mode RGBA, it contains transparency. Since JPEG cannot store an alpha channel, composite the image over a background or convert it before saving:
from PIL import Image
with Image.open("logo.png") as img:
print("Mode:", img.mode)
if img.mode == "RGBA":
background = Image.new("RGB", img.size, "white")
background.paste(img, mask=img.getchannel("A"))
background.save("logo.jpg", "JPEG")
else:
img.convert("RGB").save("logo.jpg", "JPEG")
The first branch preserves the visible appearance by placing transparent areas over a white background. The second branch converts other modes to RGB before writing a JPEG.
Common problems and fixes
ModuleNotFoundError: No module named 'PIL'
Pillow is not installed in the Python environment running the script. Install it with python -m pip install Pillow. Make sure the python command used for installation refers to the same interpreter that runs your program.
FileNotFoundError when opening an image
The filename or relative path does not point to an existing file. Check the program's current working directory, correct the relative path, or provide an absolute path.
img.format is None
The image may have been created in memory, copied, transformed into a new object, or otherwise detached from an opened source file. Inspect format immediately after Image.open() when you need the source format. For generated images, specify the output format when saving.
Saving RGBA as JPEG fails or removes transparency
JPEG does not support an alpha channel. Convert to RGB or composite the image onto a chosen background color first. A plain conversion may discard transparent pixels without giving them the background appearance you want.
Expected metadata is missing
The source may not contain that metadata, or the format plugin may expose different fields. Treat img.info as optional, inspect it safely, and use format-appropriate metadata APIs when detailed EXIF or color-profile handling is required.
The extension and detected format disagree
Filename extensions can be changed independently of encoded image data. Use Pillow's detected img.format for validation rather than trusting the extension alone.
Summary
Image.open()returns a Pillow Image object and may load pixel data lazily.img.sizeis a pixel-dimension tuple ordered as(width, height).img.formatidentifies the recognized source file format and may beNonefor newly created images.img.modedescribes the pixel representation, such asRGBorRGBA.- RGBA includes an alpha transparency channel; JPEG does not support that channel.
width,height,info,palette, andn_framesprovide additional, format-dependent information.- Inspect requirements before converting, resizing, cropping, or saving.
Next, explore RGB channels in Pillow, cropping images, and rotating an image.