• SSC Lunch Time Python
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

Lunchtime #5: Pillow¶

Why using Python for image processing?¶

  • Easy automation of image processing (compared to GUIs)
  • High-Level interfaces usable without very deep knowledge of image formats
  • Easy integration with other Python-based tools for e.g.
    • Image Analysis
    • Web Scraping
    • ML/AI

Pillow is the friendly fork of PIL, the Python Imaging Library:¶

  • PIL is/was the state-of-the-art library for image processing in Python
  • Had several issues caused by the project maintenance:
    • Compatibility issues with standard installation procedures
    • Missing open community work for issues, contributions etc.
    • Sustainability issues due to missing Continuous Integration
  • Pillow has stepped in, PIL had its last release in 2009

The Basics: Loading an image¶

We import Image from the PIL package:

In [1]:
from PIL import Image

We can open an image from disk by using open:

In [2]:
if "google.colab" in str(get_ipython()):
    !wget https://ssciwr.github.io/lunch-time-python/lunchtime5/thingstaette.png -q
img = Image.open("thingstaette.png")

The image is represented using the Image class from PIL (or one of its specialized subclasses). Images can be created by loading from file, from other images or programmatically.

The img object can be queried for a number of metadata fields of the image:

In [3]:
img.format
Out[3]:
'PNG'
In [4]:
img.size
Out[4]:
(856, 652)
In [5]:
img.width, img.height
Out[5]:
(856, 652)
In [6]:
img.mode
Out[6]:
'RGBA'
In [7]:
img.getbands()
Out[7]:
('R', 'G', 'B', 'A')

Visualizing images in Jupyter¶

To display the image directly in Jupyter notebooks, we can use the IPython's rich display system. Alternatively, img.show() can open the image in an external viewer.

In [8]:
img
Out[8]:
No description has been provided for this image

Modifying images¶

Image modifications operate on one image and return a new image which is a copy of the original with the applied modifications. This is common (good) practice in object-oriented programming.

Cropping¶

In [9]:
cropped = img.crop([330, 100, 650, 550])
In [10]:
cropped
Out[10]:
No description has been provided for this image

Resizing¶

In [11]:
resized = cropped.reduce(2)
# resized = cropped.resize((150, 100))
In [12]:
resized
Out[12]:
No description has been provided for this image

Transforming¶

In [13]:
rotated = resized.rotate(180)
In [14]:
rotated
Out[14]:
No description has been provided for this image

Applying filters¶

In [15]:
from PIL import ImageFilter
In [16]:
blurred = rotated.filter(ImageFilter.BLUR)
In [17]:
blurred
Out[17]:
No description has been provided for this image

Merging¶

Merging is done as an in-place operation on the Image object:

In [18]:
img.paste(rotated, (100, 100))
In [19]:
img
Out[19]:
No description has been provided for this image

Saving Images¶

After successful transformation, we can save the result.

  • Output format deduced from given file extension
  • Alternatively passed explicitly
  • Format conversion implemented by PIL
  • Some formats require certain conditions on the data
In [20]:
converted = img.convert("RGB")
In [21]:
converted.getbands()
Out[21]:
('R', 'G', 'B')
In [22]:
converted.save("final.jpg")

Further information¶

Pillow has much more functionality than shown here today, check the examples and references in its documentation:

https://pillow.readthedocs.io

Thanks for joining!