Documentation Menu

Concepts

The Python Imaging Library handles raster images — rectangles of pixel data.

Bands

An image can consist of one or more bands of data. Pillow allows you to store several bands in a single image, provided they all have the same dimensions and depth. For example, a PNG image might have 'R', 'G', 'B', and 'A' bands.

Working with Bands
im = Image.open("photo.png") print(im.getbands()) # ('R', 'G', 'B', 'A') # Split into individual band images r, g, b, a = im.split() # Merge bands back (maybe with a modified alpha) out = Image.merge("RGBA", (r, g, b, a))

Modes

The mode of an image defines the type and depth of a pixel. Each pixel uses the full range of the bit depth.

ModeDescriptionBands
11-bit pixels, black and white. Stored with one pixel per byte.1
L8-bit pixels, grayscale (Luminance).1
P8-bit pixels, mapped to any other mode using a colour palette.1
RGB3×8-bit pixels, true colour.3
RGBA4×8-bit pixels, true colour with transparency mask.4
CMYK4×8-bit pixels, colour separation. Used in print workflows.4
YCbCr3×8-bit pixels, colour video format (JPEG standard).3
LAB3×8-bit pixels, the L*a*b color space.3
HSV3×8-bit pixels, Hue (0-255 scaled 0-360°), Saturation, Value.3
I32-bit signed integer pixels.1
F32-bit floating point pixels.1
LAL with alpha.2
PAP with alpha.2
RGBaRGB with pre-multiplied alpha.4
LaL with pre-multiplied alpha.2
I;1616-bit unsigned integer pixels.1
I;16B16-bit big-endian unsigned integer pixels.1
Mode Conversion
# Check current mode print(im.mode) # 'RGB' # Convert to grayscale gray = im.convert("L") # Grayscale → RGB (for applying colour operations) rgb = gray.convert("RGB") # RGB → CMYK (for print) cmyk = im.convert("CMYK")

Coordinate System

Pillow uses a Cartesian coordinate system with the origin (0,0) in the upper left corner. Note that coordinates refer to pixel corners, not pixel centers. So the bounding box for a 100×100 pixel image is: (0, 0, 100, 100).

ConceptValue
OriginTop-left corner (0, 0)
X-axisIncreases rightward (width)
Y-axisIncreases downward (height)
Bounding box(left, upper, right, lower) — exclusive on right and lower

Palette Mode

Palette (P mode) images use a colour lookup table. Each pixel value is an index into this table. This is used by GIF, which is limited to 256 unique colours per frame.

Palette Operations
# Convert to palette mode — quantize to 256 colors p_img = im.convert("P") # Quantize with explicit number of colors p_img = im.quantize(colors=128) # Get the raw palette data palette = p_img.getpalette() # flat list: [R,G,B, R,G,B, ...] # Save as GIF p_img.save("output.gif")

The Info Attribute

The im.info dictionary is populated by the file decoder with format-specific metadata. Common entries include DPI, comments, and EXIF data. This dictionary is not automatically written on save() — you must explicitly pass parameters to the save method.

Reading Image Metadata
im = Image.open("photo.jpg") # Access info dict print(im.info) # {'jfif': 257, 'jfif_version': (1, 1), 'dpi': (72, 72), ...} # EXIF via getexif() from PIL import ExifTags exif = im.getexif() for tag_id, val in exif.items(): print(ExifTags.TAGS.get(tag_id, tag_id), val)

Filters

The ImageFilter module defines a set of predefined image filters and a generic kernel filter. Filters are applied using im.filter().

FilterCategoryDescription
BLURBlurBox blur.
GaussianBlur(radius)BlurGaussian bell-curve blur. Default radius=2.
BoxBlur(radius)BlurEach output pixel is the average of the square neighbourhood.
CONTOUREdgeFind image contours.
DETAILSharpenEnhance detail.
EDGE_ENHANCEEdgeEdge enhancement filter.
EDGE_ENHANCE_MOREEdgeMore aggressive edge enhancement.
EMBOSSEffectEmboss image.
FIND_EDGESEdgeFind sharp edges.
SHARPENSharpenSharpen image.
SMOOTHSmoothSmooth image.
SMOOTH_MORESmoothMore aggressive smoothing.
UnsharpMask(radius, percent, threshold)SharpenUnsharp mask. radius=2, percent=150, threshold=3.
Kernel(size, kernel)CustomCreate custom convolution kernel.
RankFilter(size, rank)RankPicks rank-th minimum pixel in each neighbourhood.
MedianFilter(size)RankPicks median pixel — good for "salt and pepper" noise.
MinFilter(size)RankPicks minimum (darkest) pixel in neighbourhood.
MaxFilter(size)RankPicks maximum (brightest) pixel in neighbourhood.