Basic Image Operations

00:00 Basic Image Operations With the Pillow Library. The Pillow library is a fork of an older library called PIL. PIL stands for Python Imaging Library, and it’s the original library that enabled Python to deal with images.

00:14 PIL was discontinued in 2011 and only supports Python 2. To use its developer’s own description, Pillow is the friendly PIL fork that kept the library alive and includes support for Python 3.

00:27 There’s more than one module in Python to deal with images and perform image processing. If you want to deal with images directly by manipulating their pixels, then you can use NumPy and SciPy.

00:39 Other popular libraries for image processing are OpenCV, scikit-image, and Mahotas. Some of these libraries are faster and more powerful than Pillow. However, Pillow remains an important tool for dealing with images.

00:54 It provides image processing features that are similar to ones found in image processing software such as Photoshop and GIMP. Pillow is often the preferred option for high-level image processing tasks that don’t require more advanced image processing expertise.

01:08 It’s also often used for exploratory work when dealing with images. Pillow has the advantage of being widely used in a Python community, and it doesn’t have the steep learning curve as some other image processing libraries.

01:22 You’ll need to install the library before you can use it. You can install Pillow using pip within a virtual environment. On-screen are the commands for windows,

01:49 and here are the commands for macOS, which will work for Linux as well.

02:06 Now that you’ve installed the package, you are ready to start familiarizing yourself with the Pillow library and perform basic manipulations of images. For the code in this part of the course, you’ll be using the image seen on-screen, which you can find in the course materials.

02:21 Make sure you’ve placed this image file in the project folder that you are working in. The main class defined in Pillow is the Image class. When you read an image using Pillow, the image is stored in an object of type Image.

02:35 When exploring images with Pillow, it’s best to use an interactive REPL environment. You’ll start by opening the building image you just saw on-screen.

02:46 You might expect to import from Pillow instead of from PIL. You did install Pillow after all and not PIL, but Pillow is a fork of the PIL library. Therefore, you’ll still need to use PIL when importing into your code.

03:05 You call the open() function to read the image from the file and .load() to read the image into memory so the file can now be closed.

03:13 You use a with statement to create a context manager to ensure the file is closed as soon as it’s no longer needed. In this example, the object is a JPEG image-specific type that’s a subclass of the Image class.

03:28 You can confirm this with a call to isinstance().

03:34 Note that both the class and the module where the class is defined share the same name, Image. You can display the image using .show().

03:44 The .show() method saves the image as a temporary file and displays it using your operating system’s native software for dealing with images.

03:52 When you run this command, you should see the image displayed as seen on-screen.

03:59 On some systems, calling .show() will block the REPL until you close the image. This depends on the operating system and the default image viewing software that you’re using.

04:09 You’ll need to be familiar with three key properties when dealing with images in Pillow. You can explore these using the Image class attributes .format, .size, and .mode.

04:22 The format of an image shows what type of image you’re dealing with. In this case, the format of the image is 'JPEG'. The size shows the width and height of the image in pixels, and the mode of this image is 'RGB'.

04:36 You’ll learn more about modes later on. Often, you may need to crop and resize images. The Image class has two methods that you can use to perform these operations: .crop() and .resize().

04:50 The argument to .crop() must be a 4-tuple that defines the left, upper, right, and bottom edges of the region that you wish to crop. The coordinate system used in Pillow assigns the coordinates (0, 0) to the pixel in the upper-left corner.

05:06 This is the same coordinate system that’s usually used for two-dimensional arrays. The 4-tuple seen here represents this section of the image.

05:25 The new image that .crop() returns has a size of 400x850 pixels. The cropped image shows only one of the buildings from the original picture.

05:40 You can also change the resolution of the cropped image using .resize(), which needs a tuple as a required argument. The tuple that you use as an argument defines the new width and height of the image in pixels.

06:00 In this case, you are setting the new width and height to a quarter of their original values using the floor division operator (//) and the Image attributes .width and .height.

06:09 The final call to show() displays the cropped and resized image.

06:18 There are additional optional parameters that you can use with .resize() to control how the image is resampled. Alternatively, you can achieve similar scaling using .reduce().

06:32 The argument determines the factor by which you scale the image down. If you prefer to set a maximum size rather than a scaling factor, then you can use .thumbnail().

06:44 The size of the thumbnail will be smaller than or equal to the size that you set. Note that the .thumbnail() method changes the Image object in place and doesn’t return a new object, but .crop(), .resize(), and .reduce() all return a new Image object.

07:01 Not all methods in the Pillow library behave in the same way. Once you’re happy with your returned image, you can save any of the Image objects to a file using .save().

07:16 Once you call the method, it creates the image files in your project folder. In this example, one of the images is a JPEG image, and the other is a PNG image.

07:26 The extension that you use as a filename automatically determines the file format, or you can specify the format as an additional optional argument. Note that there is no confirmation given if you’re going to overwrite an existing file, so you need to be careful when using the .save() method.

07:44 Now that you’ve started using Pillow, in the next section of the course, you’ll perform some basic image manipulation.

Rahul Pandey on Aug. 16, 2023

When you pillow is the fork of the PIL Library, what does it mean? What does ‘fork’ mean in this perspective?

Bartosz Zaczyński RP Team on Aug. 16, 2023

@Rahul A fork is a common technical term used to mean a copy of a project, which is developed independently from the original. For exmaple, MariaDB is a fork of MySQL.

Niels Rikze on Aug. 16, 2023

Where can I find the images used? Can’t seem to find them in the supporting material....

Bartosz Zaczyński RP Team on Aug. 16, 2023

@Niels Rikze Thanks for flagging it, and sorry for the trouble. I’ve re-uploaded an archive with the sample code, which should now have the missing images. Can you try downloading the materials again, please?

Niels Rikze on Aug. 17, 2023

Yes I can see the images now as part of the materials zip. Thanks!

Become a Member to join the conversation.