Analytics Vidhya
Published in

Analytics Vidhya

Some Interesting Tricks in Python Pillow

Just in time snippets, python image manipulation library.

Photo by Matthew Fassnacht on Unsplash

Photo by Daniel Marcinkowski on Unsplash

Image manipulation is basically a process of transforming digitised image into a desired image. Most of the times, when people think of image manipulation, photoshop is what comes to mind. It is one of the most popularly used tools out there for changing and improving images. However, this post is focused on Python image manipulation library, pillow to be exact.

According to The Hitchhiker’s Guide to Python, most image processing and manipulation techniques can be carried out effectively using two libraries: Python Imaging Library (PIL) and Open Source Computer Vision (OpenCV).

Pillow is a fork of PIL (Python Image Library), started and maintained by Alex Clark and Contributors. Originally based on the PIL code, it evolved to a better, modern and friendlier version of PIL. It supports opening and manipulating of images of many different file formats.

If you are familiar with Python Programming Language, chances are you have come across and probably used Pillow already.

Basic Installation

First, you need to have python installed on your machine. Also make sure python pip (Python Package Index) is installed and up to date. To install pillow, run the command below:

$ pip install Pillow

Now that you have installed Pillow successfully, there are some snippets below, which you might find very handy (at least I do). Note that the samples below are basic image manipulations such as resizing, blurring, grayscale conversion among others.

Convert to Grayscale (black and white)

The snippet below converts an image (test_image.jpg) to basic grayscale. Saves it as new image (test_image_grayscale.jpg).

from PIL import Image# open colour image
img = Image.open("test_image.jpg")
# convert image to black and white
img = img.convert("1")
# save new image
img.save("test_image_grayscale.jpg")
# show image in preview
img.show()
Photo by Ina Sonne on Instagram

Generate a Thumbnail

Often, we need to quickly thumbnail several images. The snippets below does the trick.

from PIL import Image# open image
img = Image.open("test_image.jpg")
# set the maximum width and height for the thumbnail
max_thumbnail_size = (200, 200)
# applying size for thumbnail
img.thumbnail(max_thumbnail_size)
# creating thumbnail
img.save("test_image_thumb.jpg")
# show image in preview
img.show()
Photo by Ishan @seefromthesky on Unsplash

Replace Colour (RGB)

The code below replaces all white pixels and replaces them with yellow. More tweak is required in order to adjust images with multiple colours. Nevertheless, the snippet below works well with images with solid background colours.

from PIL import Image# open image
img = Image.open("test_image.jpg")
img = img.convert("RGB")
datas = img.getdata()new_image_data = []for item in datas:
# change all white (also shades of whites) pixels to yellow
if item[0] in list(range(190, 256)):
new_image_data.append((255, 204, 100))
else:
new_image_data.append(item)
# update image data
img.putdata(new_image_data)
# save new image
img.save("test_image_altered_background.jpg")
# show image in preview
img.show()
Image from Google Spreadsheet API

Add Borders

This accepts the colour and size of the border to be applied to the image. The border could be an integer value such as 5, which indicates all borders (left, top, right and bottom) have the same size. It Also accepts tuple i.e. (5, 10, 5, 10), each side of having a different value.

from PIL import Image, ImageOps# open image
img = Image.open("test_image.jpg")
# border color
color = "green"
# top, right, bottom, left
border = (20, 10, 20, 10)
new_img = ImageOps.expand(img, border=border, fill=color)# save new image
new_img.save("test_image_result.jpg")
# show new bordered image in preview
new_img.show()

When applying a border to the image sample as above, it should look like the figure below.

Image from Google Spreadsheet API

Add Blurred Edges

This section consists of several steps in respect to the previous examples. The first part requires creating a blurred image (mask) and using that image as a mask for the original image. The steps and procedures on how to create a blurred edge image are well stated below.

from PIL import Image, ImageFilter# blur radius and diameter
radius, diameter = 20, 40
# open an image
img = Image.open("test_image.jpg")
# Paste image on white background
background_size = (img.size[0] + diameter, img.size[1] + diameter)
background = Image.new('RGB', background_size, (255, 255, 255))
background.paste(img, (radius, radius))
# create new images with white and black
mask_size = (img.size[0] + diameter, img.size[1] + diameter)
mask = Image.new('L', mask_size, 255)
black_size = (img.size[0] - diameter, img.size[1] - diameter)
black = Image.new('L', black_size, 0)
# create blur mask
mask.paste(black, (diameter, diameter))
# Blur image and paste blurred edge according to mask
blur = background.filter(ImageFilter.GaussianBlur(radius / 2))
background.paste(blur, mask=mask)
background.save("test_image_blurred.jpg", quality=100))# show blurred edged image in preview
background.show()
Photo by Ina Sonne on Instagram

Add Watermarks

Using watermark is one of the oldest trick in the book used to protect image from piracy. Even though there are several new approaches to evade watermarks on images (find out if you are curious), it is still very efficient. The code sample below illustrate how to add sequential watermark across an image.

from PIL import Image, ImageDraw, ImageFont# open image to apply watermark to
img = Image.open("watermark_test.jpg")
img.convert("RGB")
# get image size
img_width, img_height = img.size
# 5 by 4 water mark grid
wm_size = (int(img_width * 0.20), int(img_height * 0.25))
wm_txt = Image.new("RGBA", wm_size, (255, 255, 255, 0))
# set text size, 1:40 of the image width
font_size = int(img_width / 40)
# load font e.g. gotham-bold.ttf
font = ImageFont.truetype(path.format("gotham-bold.ttf"), font_size)
d = ImageDraw.Draw(wm_txt)
wm_text = "Kuma Kum"# centralize text
left = (wm_size[0] - font.getsize(wm_text)[0]) / 2
top = (wm_size[1] - font.getsize(wm_text)[1]) / 2
# RGBA(0, 0, 0, alpha) is black
# alpha channel specifies the opacity for a colour
alpha = 75
# write text on blank wm_text image
d.text((left, top), wm_text, fill=(0, 0, 0, alpha), font=font)
# uncomment to rotate watermark text
# wm_txt = wm_txt.rotate(15, expand=1)
# wm_txt = wm_txt.resize(wm_size, Image.ANTIALIAS)
for i in range(0, img_width, wm_txt.size[0]):
for j in range(0, img_height, wm_txt.size[1]):
img.paste(wm_txt, (i, j), wm_txt)
# save image with watermark
img.save("watermark-image.jpg")
# show image with watermark in preview
img.show()
Photo by Kuma Kum on Unsplash

So there you go!

You can use the Pillow Library for a lot more. The above are just a few basic samples, which i frequently used and consider especially useful. Try it out yourself, the full code snippets and more… can be found by clicking right here.

--

--

--

Analytics Vidhya is a community of Analytics and Data Science professionals. We are building the next-gen data science ecosystem https://www.analyticsvidhya.com

Recommended from Medium

Basic firebase realtime trigger

MediaPipe FaceMesh for Emotion Recognition using Flutter

Using Serverless Technologies to Create a Simple, Low-Cost Twitter Bot

groups of people working

mUSD Upgrade Coming Up

OverTheWire Advent writeup — Boxy

Sync The Source Code From TFVS to Github Automatically.

Input ID array. This sentence only contained a single

Anton Nell closes support for various DeFi networks — Alternative Rubyswap

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Suleiman

Suleiman

Software engineer, runner, hiker, fitness enthusiast. https://namieluss.com

More from Medium

Solving LeetCode-Climbing Stairs With Python

The Python Series #4 — While Loop and General Terminologies

Python Advance Level — Object Oriented Programming(Part I)

Python’s Types Live with Objects, Variables are Relative