Reading the Pillow Docs
I just launched a Flask server where I used the Python Image Library to do some stuff, and I had some trouble initially getting it to work correctly. I quickly read the docs and took some notes so I have a better idea of how the library works / what its capabilities are.
Overview
Pillow is a friendly PIL fork by Jeffrey A Clark and contributors. PIL is the Python Image Library by Fredricj Lundh and contributors. The Python Imaging Library adds image processing capabilities to your Python interpreter. This library provides extensive file format support, an efficient internal representation, and fairly powerful image processing capabilities. The core library is designed for fask access to data stored in a few basic pixel formats. It should provide a solid foundation for a general image processing tool.
Installation
$ python3 -m pip install --upgrade pip
$ python3 -m pip install --upgrade Pillow
Handbook
Overview
The Python Imaging Library adds image processing capabilities to your Python interpreter. This library provides extensive file format support, an efficient internal representation, and fairly powerful image processing capabilities. The core library is designed for fast access to data stored in a few basic pixel formats.
Image Archives
PIL is ideal for image archival and batch processing applications. You can use the library to create thumbnails, convert between file formats, print images, etc. The current version identifies an reads a large number of formats. Write support is intentionally restricted to the most commonly used interchaneg and presentation formats.
Image Processing
The library contains basic image processing functionality, including point operations, filtering with a set of built-in convolution kernels, and color space conversions. The library also supports image resizing, rotation, and arbitrary affine transformations. There are methods to let you pull statistics out of an image.
Tutorial
!pip install pillow
import os
from PIL import Image
path_to_image = os.path.join(os.getcwd(),'Autumn_On _the_Hudson_River.jpg')
im = Image.open(path_to_image)
print(im.format,im.size,im.mode)
display(im) # Jupyter Notebooks built-in method: https://stackoverflow.com/questions/26649716/how-to-show-pil-image-in-ipython-notebook
Reading and Writing Images
The PIL supports a wide variety of image formats. To read files from disk, use the open() function in the Image module. The library automatically determined the format based on the contents of the file. To save a file, use the save() method of the Image class. When saving, namesbecome important - the library uses the extension to discover which format to use. You can also provide a second argument to the save() method that specifies the format.
import os, sys
from PIL import Image
for infile in sys.argv[1:]:
f, e = os.path.splitext(infile)
outfile = f + ".png"
if infile != outfile:
try:
with Image.open(infile) as im:
im.save(outfile)
except OSError:
print("cannot convert",infile)
When you open a file, teh file header is read to determine the file format and extract things like mode, size, and other properties required to decode the file, but the rest of the file is not processed until later.
Cutting, Pasting, and Merging Images
The Image class provides methods allowing you to manipulate regions within an image - i.e., to extract a rectange, use the crop() method.
box = (0,0,im.size[0],100) # (left, upper, right, lower)
region = im.crop(box)
display(region)
region_new = region.transpose(Image.Transpose.ROTATE_180)
im.paste(region,box)
display(im)
"""
Merging Images
"""
def merge(im1: Image.Image, im2: Image.Image) -> Image.Image:
w = im1.size[0] + im2.size[0]
h = max(im1.size[1], im2.size[1])
im = Image.new("RGBA", (w, h))
im.paste(im1)
im.paste(im2, (im1.size[0], 0))
return im
Spliting and Merging Bands
Note that for a single-band image, split() returns the image itself. To work with individual color bands, you may want to convert the image to "RBG" first.
r, g, b = im.split()
im = Image.merge("RGB", (b,g,r))
display(im)
Geometrical Transforms
The PIL.Image.Image class contains methods to resize() and rotate() an image. The former takes a tuple giving the new size, and the latter the angle in degrees counter-clockwise:
You can easily tanspose a width the transpose() method. You can use Image.Transpose.ROTATE_[90|180|270].
im = Image.open(path_to_image)
out = im.resize((128, 128))
display(out)
out = im.rotate(45) # degrees counter-clockwise
display(out)
Relative Resizing
Color Transforms
PIL allows you to convert images between different pixel representations using the convert() method. The library supports transforms between each supported mode and the "L" and "RBG" modes.
Image Enhacement
There are a number of methods and modules that can be used to enhance images. The ImageFilter module contains a number of pre-defined enhancement filters that can be used with the filter() method.
from PIL import ImageFilter
out = im.filter(ImageFilter.DETAIL)
display(out)
out = im.filter(ImageFilter.BLUR)
display(out)
out = im.filter(ImageFilter.FIND_EDGES)
display(out)
# And Others
The point method can be used to translate pixel values of an image. In most cases, a function object expecting one argument can be passed to this method.
out = im.point(lambda x: (x * 6 - 70) / 2)
display(out)
Image Sequences
The PIL library contains some basic support for image sequences (also called animation formats). Supported sequence formats includeFIL/FLC, GIF, and a few experimental formats. When you open a sequence file, PIL automatically loads the first frame in the sequence. You can use the seek and tell methods to move between different frames:
path_to_gif = os.path.join(os.getcwd(),"standard_convolution.gif")
with Image.open("animation.gif") as im:
im.seek(1) # skip to the second frame
try:
while 1:
im.seek(im.tell() + 1)
# do something to im
except EOFError:
pass # end of sequence
Other ways to Read Files
- From a URL
from PIL import Image
from urllib.request import urlopen
url = "https://python-pillow.org/assets/images/pillow-logo.png"
img = Image.open(urlopen(url))
- From a tar archive
from PIL import Image, TarIO
fp = TarIO.TarIO("hopper.tar", "hopper.jpg")
im = Image.open(fp)
- From binary data
from PIL import Image
import io
im = Image.open(io.BytesIO(buffer))
Concepts
PIL handles raster images; that is, rectangles of pixel data.
Bands
An image can consist of one or more bands of data. The PIL allows you to store several bands in a single image, provioded they all have the same dimensions and depth - i.e., a PNG image might have 'R', 'G', 'B', and 'A' bands. To get the number and names of bands in an image, use the getbands() method.
Modes
The mode of an image is a string which defines the type and depth of a pixel in the image. Each pixel uses the full range of the bit depth. So a 1-bit pixel has a range of 0-1, an 8-bitpixel has a range of 0-255, a 32-signed integer pixel has the range of INT32 and a 32-bit floating point pixel has the range of FLOAT32. Supported Modes
Size
You can read the image size through the size attribute. This is a 2-tuple, containing the horizontal and vertical size in pixels.
Coordinate System
The PIL uses a Cartesian coordinate system, with (0,0) in the upper left corner. Note that the coordinates refer to the implied pixel corders.
Info
You can attach auxialry information to an image using the info attribute. This is a dictionary object. How much information is handled when loading and saving image files is up to the file format handler.
Transparency
If an image does not have an alpha band, transparency may be specified in the info attribute with a “transparency” key.