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:
from PIL import Image
We can open an image from disk by using open
:
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:
img.format
'PNG'
img.size
(856, 652)
img.width, img.height
(856, 652)
img.mode
'RGBA'
img.getbands()
('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.
img
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¶
cropped = img.crop([330, 100, 650, 550])
cropped
Resizing¶
resized = cropped.reduce(2)
# resized = cropped.resize((150, 100))
resized
Transforming¶
rotated = resized.rotate(180)
rotated
Applying filters¶
from PIL import ImageFilter
blurred = rotated.filter(ImageFilter.BLUR)
blurred
Merging¶
Merging is done as an in-place operation on the Image
object:
img.paste(rotated, (100, 100))
img
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
converted = img.convert("RGB")
converted.getbands()
('R', 'G', 'B')
converted.save("final.jpg")
Further information¶
Pillow has much more functionality than shown here today, check the examples and references in its documentation:
Thanks for joining!