Pillow online course

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

Mode | Channels or representation | Transparency support | Typical scenario1 | 1-bit black and white | No separate alpha channel | Strictly binary imagesL | 8-bit grayscale luminance | No separate alpha channel | Black-and-white photographsLA | 8-bit grayscale plus alpha | Yes, through alpha | Grayscale images with transparencyP | Paletted colors mapped through a palette | May include transparency information | Indexed-color images and some GIF filesRGB | Red, green, and blue channels | No alpha channel | Standard color photographs and JPEG filesRGBA | Red, green, blue, and alpha channels | Yes | Logos, overlays, and transparent PNG filesCMYK | Cyan, magenta, yellow, and black channels | No standard alpha channel | Print-oriented images

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:

Attribute | Typical value or type | Meaning | Common usesize | Tuple such as (1920, 1080) | Width and height in pixels | Dimension checks, crop bounds, and resizingwidth | Integer | Horizontal pixel count | Direct width comparisonsheight | Integer | Vertical pixel count | Direct height comparisonsformat | String such as JPEG or PNG, or None | Format detected for the opened source | File validation and format decisionsmode | String such as RGB or RGBA | Pixel and channel representation | Conversion and compatibility checksinfo | Dictionary | Available file-specific metadata | Reading optional DPI, text, profile, or other valuespalette | Palette object or None | Color lookup information for palette-based images | Inspecting P-mode imagesn_frames | Integer when supported | Number of frames in a multi-frame image | Processing animated or multi-page files

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:

  1. Open the source image.
  2. Read the properties relevant to your requirements.
  3. Decide whether the image is valid or requires processing.
  4. Only then convert, resize, crop, or save it.
  5. 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.size is a pixel-dimension tuple ordered as (width, height).
  • img.format identifies the recognized source file format and may be None for newly created images.
  • img.mode describes the pixel representation, such as RGB or RGBA.
  • RGBA includes an alpha transparency channel; JPEG does not support that channel.
  • width, height, info, palette, and n_frames provide additional, format-dependent information.
  • Inspect requirements before converting, resizing, cropping, or saving.

Next, explore RGB channels in Pillow, cropping images, and rotating an image.