Manipulation of Images With Python
Manipulation of Images With Python
library
Project report
Before you can develop predictive models for image data, you must learn how to load and
The most popular and de facto standard library in Python for loading and working with image
data is Pillow. Pillow is an updated version of the Python Image Library, or PIL, and supports a
range of simple and sophisticated image manipulation functionality. It is also the basis for
simple image support in other Python libraries such as SciPy and Matplotlib.
In this report, you will discover how to load and manipulate image data using the Pillow
Python library.
manipulating images.
It was developed and made available more than 25 years ago and has become a de facto
standard API for working with images in Python. The library is now defunct and no longer
manipulation in Python. It is even required for simple image loading and saving in other Python
If you manage the installation of Python software packages yourself for your workstation, you
Pillow is built on top of the older PIL and you can confirm that the library was installed
Running the example will print the version number for Pillow; your version number should be
Now that your environment is set up, let’s look at how to load an image.
We need a test image to demonstrate some important features of using the Pillow library.
In this tutorial, we will use a photograph of the Sydney Opera House, taken by Ed Dunens and
made available on Flickr under a creative commons license, some rights reserved.
Images are typically in PNG or JPEG format and can be loaded directly using the open()
function on Image class. This returns an Image object that contains the pixel data for the
image as well as details about the image. The Image class is the main workhorse for the
Pillow library and provides a ton of properties about the image as well as functions that allow
The ‘format‘ property on the image will report the image format (e.g. JPEG), the ‘ mode‘ will
report the pixel channel format (e.g. RGB or CMYK), and the ‘ size‘ will report the dimensions of
The show() function will display the image using your operating systems default application.
The example below demonstrates how to load and show an image using the Image class in the
Pillow library.
4 image = Image.open('opera_house.jpg')
6 print(image.format)
7 print(image.mode)
8 print(image.size)
9 # show the image
10 image.show()
Running the example will first load the image, report the format, mode, and size, then show
1 JPEG
2 RGB
3 (640, 360)
Sydney Opera House Displayed Using the Default Image Preview Application
Now that you know how to load an image, let’s look at how you can access the pixel data of
images.
With Pillow installed, you can also use the Matplotlib library to load the image and display it
This can be achieved using the imread() function that loads the image an array of pixels
directly and the imshow() function that will display an array of pixels as an image.
The example below loads and displays the same image using Matplotlib that, in turn, will use
5 data = image.imread('opera_house.jpg')
7 print(data.dtype)
8 print(data.shape)
10 pyplot.imshow(data)
11 pyplot.show()
Running the example first loads the image and then reports the data type of the array, in this
case, 8-bit unsigned integers, then reports the shape of the array, in this case, 360 pixels wide
by 640 pixels high and three channels for red, green, and blue.
1 uint8
2 (360, 640, 3)
The Matplotlib wrapper functions can be more effective than using Pillow directly.
Nevertheless, you can access the pixel data from a Pillow Image. Perhaps the simplest way is
to construct a NumPy array and pass in the Image object. The process can be reversed
converting a given array of pixel data into a Pillow Image object using
the Image.fromarray() function. This can be useful if image data is manipulated as a NumPy
array and you then want to save it later as a PNG or JPEG file.
The example below loads the photo as a Pillow Image object and converts it to a NumPy array,
5 image = Image.open('opera_house.jpg')
7 data = asarray(image)
8 # summarize shape
9 print(data.shape)
11 image2 = Image.fromarray(data)
13 print(image2.format)
14 print(image2.mode)
15 print(image2.size)
Running the example first loads the photo as a Pillow image then converts it to a NumPy array
and reports the shape of the array. Finally, the array is converted back into a Pillow image and
1 (360, 640, 3)
2 JPEG
3 RGB
4 (640, 360)
Both approaches are effective for loading image data into NumPy arrays, although the
Matplotlib imread() function uses fewer lines of code than loading and converting a Pillow
5 loaded_images = list()
7 # load image
Now that we know how to load images as NumPy arrays, let’s look at how to save images to
file.
For example, the code listing below loads the photograph in JPEG format and saves it in PNG
format.
4 image = Image.open('opera_house.jpg')
6 image.save('opera_house.png', format='PNG')
8 image2 = Image.open('opera_house.png')
9 print(image2.format)
Running the example loads the JPEG image, saves it in PNG format, then loads the newly
saved image again, and confirms that the format is indeed PNG.
1 PNG
Saving images is useful if you perform some data preparation on the image before modeling.
There are a number of ways to convert an image to grayscale, but Pillow provides
the convert() function and the mode ‘L‘ will convert an image to grayscale.
1 # example of saving a grayscale version of a loaded image
4 image = Image.open('opera_house.jpg')
6 gs_image = image.convert(mode='L')
7 # save in jpeg format
8 gs_image.save('opera_house_grayscale.jpg')
10 image2 = Image.open('opera_house_grayscale.jpg')
12 image2.show()
Running the example loads the photograph, converts it to grayscale, saves the image in a new
file, then loads it again and shows it to confirm that the photo is now grayscale instead of
color.
Sometimes it is desirable to thumbnail all images to have the same width or height. This can
be achieved with Pillow using the thumbnail() function. The function takes a tuple with the
width and height and the image will be resized so that the width and height of the image are
For example, the test photograph we have been working with has the width and height of (640,
360). We can resize it to (100, 100), in which case the largest dimension, in this case, the
width, will be reduced to 100, and the height will be scaled in order to retain the aspect ratio
of the image.
The example below will load the photograph and create a smaller thumbnail with a width and
4 image = Image.open('opera_house.jpg')
6 print(image.size)
8 image.thumbnail((100,100))
10 print(image.size)
Running the example first loads the photograph and reports the width and height. The image is
then resized, in this case, the width is reduced to 100 pixels and the height is reduced to 56
1 (640, 360)
2 (100, 56)
We may not want to preserve the aspect ratio, and instead, we may want to force the pixels
This can be achieved using the resize() function that allows you to specify the width and
height in pixels and the image will be reduced or stretched to fit the new shape.
The example below demonstrates how to resize a new image and ignore the original aspect
ratio.
4 image = Image.open('opera_house.jpg')
6 print(image.size)
8 img_resized = image.resize((200,200))
10 print(img_resized.size)
Running the example loads the image, reports the shape of the image, then resizes it to have a
1 (640, 360)
2 (200, 200)
The sized of the image is shown and we can see that the wide photograph has been
compressed into a square, although all of the features are still quite visible and obvious.
Standard resampling algorithms are used to invent or remove pixels when resizing, and you
can specify a technique, although default is a bicubic resampling algorithm that suits most
general applications.
Resized Photograph That Does Not Preserve the Original Aspect Ratio
How to Flip, Rotate, and Crop Images
Simple image manipulation can be used to create new versions of images that, in turn, can
Generally, this is referred to as data augmentation and may involve creating flipped, rotated,
cropped, or other modified versions of the original images with the hope that the algorithm will
learn to extract the same features from the image data regardless of where they might
appear.
You may want to implement your own data augmentation schemes, in which case you need to
Flip Image
An image can be flipped by calling the flip() function and passing in a method such
as FLIP_LEFT_RIGHT for a horizontal flip or FLIP_TOP_BOTTOM for a vertical flip. Other flips
The example below creates both horizontal and vertical flipped versions of the image.
4 # load image
5 image = Image.open('opera_house.jpg')
6 # horizontal flip
7 hoz_flip = image.transpose(Image.FLIP_LEFT_RIGHT)
8 # vertical flip
9 ver_flip = image.transpose(Image.FLIP_TOP_BOTTOM)
11 pyplot.subplot(311)
12 pyplot.imshow(image)
13 pyplot.subplot(312)
14 pyplot.imshow(hoz_flip)
15 pyplot.subplot(313)
16 pyplot.imshow(ver_flip)
17 pyplot.show()
Running the example loads the photograph and creates horizontal and vertical flipped versions
of the photograph, then plots all three versions as subplots using Matplotlib.
You will note that the imshow() function can plot the Image object directly without having to
Rotate Image
An image can be rotated using the rotate() function and passing in the angle for the rotation.
The function offers additional control such as whether or not to expand the dimensions of the
image to fit the rotated pixel values (default is to clip to the same size), where to center the
rotation the image (default is the center), and the fill color for pixels outside of the image
(default is black).
4 # load image
5 image = Image.open('opera_house.jpg')
7 pyplot.subplot(311)
8 pyplot.imshow(image)
9 # rotate 45 degrees
10 pyplot.subplot(312)
11 pyplot.imshow(image.rotate(45))
12 # rotate 90 degrees
13 pyplot.subplot(313)
14 pyplot.imshow(image.rotate(90))
15 pyplot.show()
Running the example plots the original photograph, then a version of the photograph rotated
You can see that in both rotations, the pixels are clipped to the original dimensions of the
image and that the empty pixels are filled with black color.
Plot of Original and Rotated Version of a Photograph
Cropped Image
An image can be cropped: that is, a piece can be cut out to create a new image, using
The crop function takes a tuple argument that defines the two x/y coordinates of the box to
crop out of the image. For example, if the image is 2,000 by 2,000 pixels, we can clip out a 100
by 100 box in the middle of the image by defining a tuple with the top-left and bottom-right
The example below demonstrates how to create a new image as a crop from a loaded image.
4 image = Image.open('opera_house.jpg')
8 cropped.show()
Running the example creates a cropped square image of 100 pixels starting at 100,100 and
extending down and left to 200,200. The cropped square is then displayed.
THE END