Every Pillow task starts from an Image object, and knowing what open actually does avoids file-handle and lazy-loading surprises.
Pillow is installed as pillow but imported as PIL: from PIL import Image. The central class is `Image.Image`.
Image.open(path_or_file) identifies the format from the file's contents, not its extension, and returns an Image. Useful attributes:
im.format: the detected file format, such as"JPEG"or"PNG"(Nonefor images you create)im.size: a(width, height)tuple, alsoim.widthandim.heightim.mode: how pixels are stored, such as"RGB","RGBA"or"L"(grayscale)
Image.open is lazy: it reads only the header. Pixel data is decoded when you first need it, or when you call im.load(). The file stays open until then, so use a with block, which closes the file when you are done. If you need the pixels after the block, call im.load() or make a copy inside it.
Image.new(mode, size, color) creates a blank image; colours can be tuples, ints or names like "skyblue" and "#ff8800".
Most methods return a new image rather than changing the original: im.resize(...), im.convert(...), im.rotate(...). A few operate in place and return None, notably im.thumbnail(...) and im.paste(...).
im.getpixel((x, y)) and im.putpixel read and write single pixels; they are fine for a few values, but far too slow for loops over a whole image.
Example
from PIL import Image
im = Image.new("RGB", (320, 200), "skyblue") # mode, (width, height), colour
print(im.size, im.mode, im.format) # (320, 200) RGB None
im.save("sky.png")
with Image.open("sky.png") as img: # lazy: header only so far
print(img.format, img.size, img.mode) # PNG (320, 200) RGB
print(img.width, img.height) # 320 200
print(img.getpixel((10, 10))) # (135, 206, 235)
img.load() # decode pixels now
bigger = im.resize((640, 400)) # returns a NEW image
print(im.size, bigger.size) # (320, 200) (640, 400)Remember
- Install
pillow, importfrom PIL import Image sizeis (width, height);modesays how pixels are storedImage.openis lazy and detects the format from content- Most methods return new images; thumbnail and paste work in place
Watch out for
- Writing
im.resize((w, h))and expectingimitself to change: assign the returned image.