Python Image Manipulation

Exclusive offer: get 50% off this eBook here
Python Multimedia

Python Multimedia — Save 50%

Learn how to develop Multimedia applications using Python with this practical step-by-step guide

€20.99    €10.50
by Ninad Sathaye | August 2010 | Beginner's Guides Web Development Web Graphics & Video

In this article by Ninad Sathaye, author of Python Multimedia Beginner's Guide, explains basic image conversion and manipulation techniques using the Python Imaging Library. With the help of several examples and code snippets, we will perform some basic manipulations on the image, such as pasting an image on to another, resizing, rotating/ flipping, cropping, and so on. We will write tools to capture a screenshot and convert image files between different formats.

Specifically, we shall:

  • Learn various image I/O operations for reading and writing images using the Python Imaging Library (PIL)
  • With the help of several examples and code snippets, perform some basic manipulations on the image
  • develop a small application that captures a region of your screen at regular time intervals using ImageGrab.

(For more resources on Python, see here.)

So let's get on with it!

Installation prerequisites

Before we jump in to the main topic, it is necessary to install the following packages.

Python

In this article, we will use Python Version 2.6, or to be more specific, Version 2.6.4. It can be downloaded from the following location: http://python.org/download/releases/

Windows platform

For Windows, just download and install the platform-specific binary distribution of Python 2.6.4.

Other platforms

For other platforms, such as Linux, Python is probably already installed on your machine. If the installed version is not 2.6, build and install it from the source distribution. If you are using a package manager on a Linux system, search for Python 2.6. It is likely that you will find the Python distribution there. Then, for instance, Ubuntu users can install Python from the command prompt as:

$sudo apt-get python2.6

Note that for this, you must have administrative permission on the machine on which you are installing Python.

Python Imaging Library (PIL)

We will learn image-processing techniques by making extensive use of the Python Imaging Library (PIL) throughout this article. PIL is an open source library. You can download it from http://www.pythonware.com/products/pil/. Install the PIL Version 1.1.6 or later.

Windows platform

For Windows users, installation is straightforward—use the binary distribution PIL 1.1.6 for Python 2.6.

Other platforms

For other platforms, install PIL 1.1.6 from the source. Carefully review the README file in the source distribution for the platform-specific instructions. Libraries listed in the following table are required to be installed before installing PIL from the source. For some platforms like Linux, the libraries provided in the OS should work fine. However, if those do not work, install a pre-built "libraryName-devel" version of the library. For example, for JPEG support, the name will contain "jpeg-devel-", and something similar for the others. This is generally applicable to rpm-based distributions. For Linux flavors like Ubuntu, you can use the following command in a shell window.

$sudo apt-get install python-imaging

However, you should make sure that this installs Version 1.1.6 or later. Check PIL documentation for further platform-specific instructions. For Mac OSX, see if you can use fink to install these libraries. See http://www.finkproject.org/ for more details. You can also check the website http://pythonmac.org or Darwin ports website http://darwinports.com/ to see if a binary package installer is available. If such a pre-built version is not available for any library, install it from the source.

The PIL prerequisites for installing PIL from source are listed in the following table:

Library URL Version Installation options
(a) or (b)
libjpeg (JPEG support) http://www.ijg.org/files 7 or 6a or 6b (a) Pre-built version. For example:
jpeg-devel-7
Check if you can do:
sudo apt-install libjpeg (works on some flavors of Linux)
(b) Source tarball. For example: jpegsrc.v7.tar.gz

zib

(PNG support)

http://www.gzip.org/zlib/ 1.2.3 or later (a) Pre-built version. For example:
zlib-devel-1.2.3..
(b) Install from the source.
freetype2
(OpenType /TrueType support)
http://www.freetype.org 2.1.3 or later (a) Pre-built version. For example:
freetype2-devel-2.1.3..
(b) Install from the source.

PyQt4

This package provides Python bindings for Qt libraries. We will use PyQt4 to generate GUI for the image-processing application that we will develop later in this article. The GPL version is available at: http://www.riverbankcomputing.co.uk/software/pyqt/download.

Windows platform

Download and install the binary distribution pertaining to Python 2.6. For example, the executable file's name could be 'PyQt-Py2.6-gpl-4.6.2-2.exe'. Other than Python, it includes everything needed for GUI development using PyQt.

Other platforms

Before building PyQt, you must install SIP Python binding generator. For further details, refer to the SIP homepage: http://www.riverbankcomputing.com/software/sip/.

After installing SIP, download and install PyQt 4.6.2 or later, from the source tarball. For Linux/Unix source, the filename will start with PyQt-x11-gpl-.. and for Mac OS X, PyQt-mac-gpl-... Linux users should also check if PyQt4 distribution is already available through the package manager.

Summary of installation prerequisites

 

Package Download location Version Windows platform Linux/Unix/OS X platforms
Python http://python.org/download/releases/ 2.6.4 (or any 2.6.x) Install using binary distribution (a) Install from binary; Also install additional developer packages (For example, with python-devel in the package name in the rpm systems) OR
(b) Build and install from the source tarball.
(c) MAC users can also check websites such as http://darwinports.com/ or http://pythonmac.org/.
PIL http://www.pythonware.com/products/pil/ 1.1.6 or later Install PIL 1.1.6 (binary) for Python 2.6 (a) Install prerequisites if needed. Refer to Table #1 and the README file in PIL source distribution.
(b) Install PIL from source.
(c) MAC users can also check websites like http://darwinports.com/ or http://pythonmac.org/.
PyQt4 http://www.riverbankcomputing.co.uk/software/pyqt/download 4.6.2 or later Install using binary pertaining to Python 2.6 (a) First install SIP 4.9 or later.
(b) Then install PyQt4.

Python Multimedia Learn how to develop Multimedia applications using Python with this practical step-by-step guide
Published: August 2010
eBook Price: €20.99
Book Price: €34.99
See more
Select your format and quantity:

(For more resources on Python, see here.)

Reading and writing images

To manipulate an existing image, we must open it first for editing and we also require the ability to save the image in a suitable file format after making changes. The Image module in PIL provides methods to read and write images in the specified image file format. It supports a wide range of file formats.

To open an image, use Image.open method. Start the Python interpreter and write the following code. You should specify an appropriate path on your system as an argument to the Image.open method.

>>>import Image
>>>inputImage = Image.open("C:\\PythonTest\\image1.jpg")

This will open an image file by the name image1.jpg. If the file can't be opened, an IOError will be raised, otherwise, it returns an instance of class Image.

For saving image, use the save method of the Image class. Make sure you replace the following string with an appropriate /path/to/your/image/file.

>>>inputImage.save("C:\\PythonTest\\outputImage.jpg")

You can view the image just saved, using the show method of Image class.

>>>outputImage = Image.open("C:\\PythonTest\\outputImage.jpg")
>>>outputImage.show()

Here, it is essentially the same image as the input image, because we did not make any changes to the output image.

Time for action – image file converter

With this basic information, let's build a simple image file converter. This utility will batch-process image files and save them in a user-specified file format.

To get started, download the file ImageFileConverter.py from the Packt website

. This file can be run from the command line as:

python ImageConverter.py [arguments]

Here, [arguments] are:

  • --input_dir: The directory path where the image files are located.
  • --input_format: The format of the image files to be converted. For example, jpg.
  • --output_dir: The location where you want to save the converted images.
  • --output_format: The output image format. For example, jpg, png, bmp, and so on.

The following screenshot shows the image conversion utility in action on Windows XP, that is, running image converter from the command line.

Here, it will batch-process all the .jpg images within C:\PythonTest\images and save them in png format in the directory C:\PythonTest\images\OUTPUT_IMAGES.

Python Image Manipulation

The file defines class ImageConverter. We will discuss the most important methods in this class.

  • def processArgs: This method processes all the command-line arguments listed earlier. It makes use of Python's built-in module getopts to process these arguments. Readers are advised to review the code in the file ImageConverter.py in the code bundle of this book for further details on how these arguments are processed.
  • def convertImage: This is the workhorse method of the image-conversion utility.

    1 def convertImage(self):
    2 pattern = "*." + self.inputFormat
    3 filetype = os.path.join(self.inputDir, pattern)
    4 fileList = glob.glob(filetype)
    5 inputFileList = filter(imageFileExists, fileList)
    6
    7 if not len(inputFileList):
    8 print "\n No image files with extension %s located \
    9 in dir %s"%(self.outputFormat, self.inputDir)
    10 return
    11 else:
    12 # Record time before beginning image conversion
    13 starttime = time.clock()
    14 print "\n Converting images.."
    15
    16 # Save image into specified file format.
    17 for imagePath in inputFileList:
    18 inputImage = Image.open(imagePath)
    19 dir, fil = os.path.split(imagePath)
    20 fil, ext = os.path.splitext(fil)
    21 outPath = os.path.join(self.outputDir,
    22 fil + "." + self.outputFormat)
    23 inputImage.save(outPath)
    24
    25 endtime = time.clock()
    26 print "\n Done!"
    27 print "\n %d image(s) written to directory:\
    28 %s" %(len(inputFileList), self.outputDir)
    29 print "\n Approximate time required for conversion: \
    30 %.4f seconds" % (endtime - starttime)

Now let's review the preceding code.

  1. Our first task is to get a list of all the image files to be saved in a different format. This is achieved by using glob module in Python. Line 4 in the code snippet finds all the file path names that match the pattern specified by the local variable fileType. On line 5, we check whether the image file in fileList exists. This operation can be efficiently performed over the whole list using the built-in filter functionality in Python.
  2. The code block between lines 7 to 14 ensures that one or more images exist. If so, it will record the time before beginning the image conversion.
  3. The next code block (lines 17-23) carries out the image file conversion. On line 18, we use Image.open to open the image file. Line 18 creates an Image object. Then the appropriate output path is derived and finally the output image is saved using the save method of the Image module.

What just happened?

In this simple example, we learned how to open and save image files in a specified image format. We accomplished this by writing an image file converter that batch-processes a specified image file. We used PIL's Image.open and Image.save functionality along with Python's built-in modules such as glob and filter.

Now we will discuss other key aspects related to the image reading and writing.

Creating an image from scratch

So far we have seen how to open an existing image. What if we want to create our own image? As an example, it you want to create fancy text as an image, the functionality that we are going to discuss now comes in handy. Later in this book, we will learn how to use such an image containing some text to embed into another image. The basic syntax for creating a new image is:

foo = Image.new(mode, size, color)

Where, new is the built-in method of class Image. Image.new takes three arguments, namely, mode, size, and color. The mode argument is a string that gives information about the number and names of image bands. Following are the most common values for mode argument: L (gray scale) and RGB (true color). The size is a tuple specifying dimensions of the image in pixels, whereas, color is an optional argument. It can be assigned an RGB value (a 3-tuple) if it's a multi-band image. If it is not specified, the image is filled with black color.

Time for action – creating a new image containing some text

As already stated, it is often useful to generate an image containing only some text or a common shape. Such an image can then be pasted onto another image at a desired angle and location. We will now create an image with text that reads, "Not really a fancy text!"

  1. Write the following code in a Python source file:
    1 import Image
    2 import ImageDraw
    3 txt = "Not really a fancy text!"
    4 size = (150, 50)
    5 color = (0, 100, 0)
    6 img = Image.new('RGB', size, color)
    7 imgDrawer = ImageDraw.Draw(img)
    8 imgDrawer.text((5, 20), txt)
    9 img.show()
  2. Let's analyze the code line by line. The first two lines import the necessary modules from PIL. The variable txt is the text we want to include in the image. On line 7, the new image is created using Image.new. Here we specify the mode and size arguments. The optional color argument is specified as a tuple with RGB values pertaining to the "dark green" color.
  3. The ImageDraw module in PIL provides graphics support for an Image object. The function ImageDraw.Draw takes an image object as an argument to create a Draw instance. In output code, it is called imgDrawer, as used on line 7. This Draw instance enables drawing various things in the given image.
  4. On line 8, we call the text method of the Draw instance and supply position (a tuple) and the text (stored in the string txt) as arguments.
  5. Finally, the image can be viewed using img.show() call. You can optionally save the image using Image.save method. The following screenshot shows the resultant image.

Python Image Manipulation

What just happened?

We just learned how to create an image from scratch. An empty image was created using the Image.new method. Then, we used the ImageDraw module in PIL to add text to this image.

Reading images from archive

If the image is part of an archived container, for example, a TAR archive, we can use the TarIO module in PIL to open it and then call Image.open to pass this TarIO instance as an argument.

Time for action – reading images from archives

Suppose there is an archive file images.tar containing image file image1.jpg. The following code snippet shows how to read image1.jpg from the tarball.

>>>import TarIO
>>>import Images
>>>fil = TarIO.TarIO("images.tar", "images/image1.jpg")
>>>img = Image.open(fil)
>>>img.show()

What just happened?

We learned how to read an image located in an archived container.

Have a go hero – add new feature to the image file converter Modify the image conversion code so that it supports the following new functionality, which:

  1. Takes a ZIP file containing images as input
  2. Creates a TAR archive of the converted images
Python Multimedia Learn how to develop Multimedia applications using Python with this practical step-by-step guide
Published: August 2010
eBook Price: €20.99
Book Price: €34.99
See more
Select your format and quantity:

(For more resources on Python, see here.)

Basic image manipulations

Now that we know how to open and save images, let's learn some basic techniques to manipulate images. PIL supports a variety of geometric manipulation operations, such as resizing an image, rotating it by an angle, flipping it top to bottom or left to right, and so on. It also facilitates operations such as cropping, cutting and pasting pieces of images, and so on.

Resizing

Changing the dimensions of an image is one of the most frequently used image manipulation operations. The image resizing is accomplished using Image.resize in PIL. The following line of code explains how it is achieved.

foo = img.resize(size, filter)

Here, img is an image (an instance of class Image) and the result of resizing operation is stored in foo (another instance of class Image). The size argument is a tuple (width, height). Note that the size is specified in pixels. Thus, resizing the image means modifying the number of pixels in the image. This is also known as image re-sampling. The Image.resize method also takes filter as an optional argument. A filter is an interpolation algorithm used while re-sampling the given image. It handles deletion or addition of pixels during re-sampling, when the resize operation is intended to make image smaller or larger in size respectively. There are four filters available. The resize filters in the increasing order of quality are NEAREST, BILINEAR, BICUBIC, and ANTIALIAS. The default filter option is NEAREST.

Time for action – resizing

Let's now resize images by modifying their pixel dimensions and applying various filters for re-sampling.

  1. Download the file ImageResizeExample.bmp from the Packt website. We will use this as the reference file to create scaled images. The original dimensions of ImageResizeExample.bmp are 200 x 212 pixels.
  2. Write the following code in a file or in Python interpreter. Replace the inPath and outPath strings with the appropriate image path on your machine.
    1 import Image
    2 inPath = "C:\\images\\ImageResizeExample.jpg"
    3 img = Image.open(inPath)
    4 width , height = (160, 160)
    5 size = (width, height)
    6 foo = img.resize(size)
    7 foo.show()
    8 outPath = "C:\\images\\foo.jpg"
    9 foo.save(outPath)
  3. The image specified by the inPath will be resized and saved as the image specified by the outPath. Line 6 in the code snippet does the resizing job and finally we save the new image on line 9. You can see how the resized image looks by calling foo.show().
  4. Let's now specify the filter argument. In the following code, on line 14, the filterOpt argument is specified in the resize method. The valid filter options are specified as values in the dictionary filterDict. The keys of filterDict are used as the filenames of the output images. The four images thus obtained are compared in the next illustration. You can clearly notice the difference between the ANTIALIAS image and the others (particularly, look at the flower petals in these images). When the processing time is not an issue, choose the ANTIALIAS filter option as it gives the best quality image.

    1 import Image
    2 inPath = "C:\\images\\ImageResizeExample.jpg"
    3 img = Image.open(inPath)
    4 width , height = (160, 160)
    5 size = (width, height)
    6 filterDict = {'NEAREST':Image.NEAREST,
    7 'BILINEAR':Image.BILINEAR,
    8 'BICUBIC':Image.BICUBIC,
    9 'ANTIALIAS':Image.ANTIALIAS }
    10
    11 for k in filterDict.keys():
    12 outPath= "C:\\images\\" + k + ".jpg"
    13 filterOpt = filterDict[k]
    14 foo = img.resize(size, filterOpt)
    15 foo.save(outPath)

    Python Image Manipulation

  5. The resize functionality illustrated here, however, doesn't preserve the aspect ratio of the resulting image. The image will appear distorted if one dimension is stretched more or stretched less in comparison with the other dimension. PIL's Image module provides another built-in method to fix this. It will override the larger of the two dimensions, such that the aspect ratio of the image is maintained.

    import Image
    inPath = "C:\\images\\ResizeImageExample.jpg"
    img = Image.open(inPath)
    width , height = (100, 50)
    size = (width, height)
    outPath = "C:\\images\\foo.jpg"
    img.thumbnail(size, Image.ANTIALIAS)
    img.save(outPath)

  6. This code will override the maximum pixel dimension value (width in this case) specified by the programmer and replace it with a value that maintains the aspect ratio of the image. In this case, we have an image with pixel dimensions (47, 50). The resultant images are compared in the following illustration.

    It shows the comparison of output images for methods Image.thumbnail and Image.resize.

    Python Image Manipulation

What just happened?

We just learned how image resizing is done using PIL's Image module, by writing a few lines of code. We also learned different types of filters used in image resizing (re-sampling). And finally, we also saw how to resize an image while still keeping the aspect ratio intact (that is, without distortion), using the Image.thumbnail method.

Rotating

Like image resizing, rotating an image about its center is another commonly performed transformation. For example, in a composite image, one may need to rotate the text by certain degrees before embedding it in another image. For such needs, there are methods such as rotate and transpose available in PIL's Image module. The basic syntax to rotate an image using Image.rotate is as follows:

foo = img.rotate(angle, filter)

Where, the angle is provided in degrees and filter, the optional argument, is the image-re-sampling filter. The valid filter value can be NEAREST, BILINEAR, or BICUBIC. You can rotate the image using Image.transpose only for 90-, 180-, and 270-degree rotation angles.

Time for action – rotating

  1. Download the file Rotate.png from the Packt website. Alternatively, you can use any supported image file of your choice.
  2. Write the following code in Python interpreter or in a Python file. As always, specify the appropriate path strings for inPath and outPath variables.

    1 import Image
    2 inPath = "C:\\images\\Rotate.png"
    3 img = Image.open(inPath)
    4 deg = 45
    5 filterOpt = Image.BICUBIC
    6 outPath = "C:\\images\\Rotate_out.png"
    7 foo = img.rotate(deg, filterOpt)
    8 foo.save(outPath)

  3. Upon running this code, the output image, rotated by 45 degrees, is saved to the outPath. The filter option Image.BICUBIC ensures highest quality. The next illustration shows the original and the images rotated by 45 and 180 degrees respectively—the original and rotated images.
    Python Image Manipulation
  4. There is another way to accomplish rotation for certain angles by using the Image.transpose functionality. The following code achieves a 270-degree rotation. Other valid options for rotation are Image.ROTATE_90 and Image.ROTATE_180.
    import Image
    inPath = "C:\\images\\Rotate.png"
    img = Image.open(inPath)
    outPath = "C:\\images\\Rotate_out.png"
    foo = img.transpose(Image.ROTATE_270)
    foo.save(outPath)

What just happened?

In the previous section, we used Image.rotate to accomplish rotating an image by the desired angle. The image filter Image.BICUBIC was used to obtain better quality output image after rotation. We also saw how Image.transpose can be used for rotating the image by certain angles.

Flipping

There are multiple ways in PIL to flip an image horizontally or vertically. One way to achieve this is using the Image.transpose method. Another option is to use the functionality from the ImageOps module . This module makes the image-processing job even easier with some ready-made methods. However, note that the PIL documentation for Version 1.1.6 states that ImageOps is still an experimental module.

Time for action – flipping

Imagine that you are building a symmetric image using a bunch of basic shapes. To create such an image, an operation that can flip (or mirror) the image would come in handy. So let's see how image flipping can be accomplished.

  1. Write the following code in a Python source file.

    1 import Image
    2 inPath = "C:\\images\\Flip.png"
    3 img = Image.open(inPath)
    4 outPath = "C:\\images\\Flip_out.png"
    5 foo = img.transpose(Image.FLIP_LEFT_RIGHT)
    6 foo.save(outPath)

  2. In this code, the image is flipped horizontally by calling the transpose method. To flip the image vertically, replace line 5 in the code with the following:

    foo = img.transpose(Image.FLIP_TOP_BOTTOM)

  3. The following illustration shows the output of the preceding code when the image is flipped horizontally and vertically.
    Python Image Manipulation
  4. The same effect can be achieved using the ImageOps module. To flip the image horizontally, use ImageOps.mirror, and to flip the image vertically, use ImageOps.flip.

    import ImageOps

    # Flip image horizontally
    foo1 = ImageOps.mirror(img)
    # Flip image vertically
    foo2 = ImageOps.flip(img)

What just happened?

With the help of example, we learned how to flip an image horizontally or vertically using Image.transpose and also by using methods in class ImageOps. This operation will be applied later in this book for further image processing such as preparing composite images.

Capturing screenshots

How do you capture the desktop screen or a part of it using Python? There is ImageGrab module in PIL. This simple line of code will capture the whole screen.

img = ImageGrab.grab()

Where, img is an instance of class Image.

However, note that in PIL Version 1.1.6, the ImageGrab module supports screen grabbing only for Windows platform.

Time for action – capture screenshots at intervals

Imagine that you are developing an application, where, after certain time interval, the program needs to automatically capture the whole screen or a part of the screen. Let's develop code that achieves this.

  1. Write the following code in a Python source file. When the code is executed, it will capture part of the screen after every two seconds. The code will run for about three seconds.

    1 import ImageGrab
    2 import time
    3 startTime = time.clock()
    4 print "\n The start time is %s sec" % startTime
    5 # Define the four corners of the bounding box.
    6 # (in pixels)
    7 left = 150
    8 upper = 200
    9 right = 900
    10 lower = 700
    11 bbox = (left, upper, right, lower)
    12
    13 while time.clock() < 3:
    14 print " \n Capturing screen at time %.4f sec" \
    15 %time.clock()
    16 screenShot = ImageGrab.grab(bbox)
    17 name = str("%.2f"%time.clock())+ "sec.png"
    18 screenShot.save("C:\\images\\output\\" + name)
    19 time.sleep(2)

  2. We will now review the important aspects of this code. First, import the necessary modules. The time.clock() keeps track of the time spent. On line 11, a bounding box is defined. It is a 4-tuple that defines the boundaries of a rectangular region. The elements in this tuple are specified in pixels. In PIL, the origin (0, 0) is defined in the top-left corner of an image. The next illustration is a representation of a bounding box for image cropping; see how left, upper and right, lower are specified as the ends of a diagonal of rectangle.

    Example of a bounding box used for image cropping.

    Python Image Manipulation
  3. The while loop runs till the time.clock() reaches three seconds. Inside the loop, the part of the screen bounded within bbox is captured (see line 16) and then the image is saved on line 18. The image name corresponds to the time at which it is taken.
  4. The time.sleep(2) call suspends the execution of the application for two seconds. This ensures that it grabs the screen every two seconds. The loop repeats until the given time is reached.
  5. In this example, it will capture two screenshots, one when it enters the loop for the first time and the next after a two-second time interval. In the following illustration, the two images grabbed by the code are shown. Notice the time and console prints in these images.
    Python Image Manipulation

    The preceding screenshot is taken at time 00:02:15 as shown dialog. The next screenshot is taken after 2 seconds, at wall clock time, 00:02:17.

    Python Image Manipulation

    The two screenshots captured by the screenshot code at two seconds time interval. Notice the time and console print in the screenshots

What just happened?

In the preceding example, we wrote a simple application that captures the screen at regular time intervals. This helped us to learn how to grab a screen region using ImageGrab.

Cropping

In previous section, we learned how to grab a part of the screen with ImageGrab. Cropping is a very similar operation performed on an image. It allows you to modify a region within an image.

Time for action – cropping an image

This simple code snippet crops an image and applies some changes on the cropped portion.

  1. Download the file Crop.png from Packt website. The size of this image is 400 x 400 pixels. You can also use your own image file.
  2. Write the following code in a Python source file. Modify the path of the image file to an appropriate path.

    import Image
    img = Image.open("C:\\images\\Crop.png")
    left = 0
    upper = 0
    right = 180
    lower = 215
    bbox = (left, upper, right, lower)
    img = img.crop(bbox)
    img.show()

  3. This will crop a region of the image bounded by bbox. The specification of the bounding box is identical to what we have seen in the Capturing screenshots section. The output of this example is shown in the following illustration.

    Original image (left) and its cropped region (right).

Python Image Manipulation

What just happened?

In the previous section, we used Image.crop functionality to crop a region within an image and save the resultant image. In the next section, we will apply this while pasting a region of an image onto another.

Pasting

Pasting a copied or cut image onto another one is a commonly performed operation while processing images. Following is the simplest syntax to paste one image on another.

img = img.paste(image, box)

Here image is an instance of class Image and box is a rectangular bounding box that defines the region of img, where the image will be pasted. The box argument can be a 4-tupleError: Reference source not found or a 2-tuple. If a 4-tuple box is specified, the size of the image to be pasted must be same as the size of the region. Otherwise, PIL will throw an error with a message ValueError: images do not match. The 2-tuple on the other hand, provides pixel coordinates of the upper-left corner of the region to be pasted.

Now look at the following line of code. It is a copy operation on an image.

img2 = img.copy(image)

The copy operation can be viewed as pasting the whole image onto a new image. This operation is useful when, for instance, you want to keep the original image unaltered and make alterations to the copy of the image.

Time for action – pasting: mirror the smiley face!

Consider the example in earlier section where we cropped a region of an image. The cropped region contained a smiley face. Let's modify the original image so that it has a 'reflection' of the smiley face.

  1. If not already, download the file Crop.png from the Packt website.
  2. Write this code by replacing the file path with appropriate file path on your system.

    1 import Image
    2 img = Image.open("C:\\images\\Crop.png")
    3 # Define the elements of a 4-tuple that represents
    4 # a bounding box ( region to be cropped)
    5 left = 0
    6 upper = 25
    7 right = 180
    8 lower = 210
    9 bbox = (left, upper, right, lower)
    10 # Crop the smiley face from the image
    11 smiley = img.crop(bbox_1)
    12 # Flip the image horizontally
    13 smiley = smiley.transpose(Image.FLIP_TOP_BOTTOM)
    14 # Define the box as a 2-tuple.
    15 bbox_2 = (0, 210)
    16 # Finally paste the 'smiley' on to the image.
    17 img.paste(smiley, bbox_2)
    18 img.save("C:\\images\\Pasted.png")
    19 img.show()

  3. First we open an image and crop it to extract a region containing the smiley face. This was already done in section Error: Reference source not found'Cropping'. The only minor difference you will notice is the value of the tuple element upper. It is intentionally kept as 25 pixels from the top to make sure that the crop image has a size that can fit in the blank portion below the original smiley face.
  4. The cropped image is then flipped horizontally with code on line 13.
  5. Now we define a box, bbox_2, for pasting the cropped smiley face back on to the original image. Where should it be pasted? We intend to make a 'reflection' of the original smiley face. So the coordinate of the top-right corner of the pasted image should be greater than or equal to the bottom y coordinate of the cropped region, indicated by 'lower' variable (see line 8) . The bounding box is defined on line 15, as a 2-tuple representing the upper-left coordinates of the smiley.
  6. Finally, on line 17, the paste operation is performed to paste the smiley on the original image. The resulting image is then saved with a different name.
  7. The original image and the output image after the paste operation is shown in the next illustration.
    Python Image Manipulation

    The illustration shows the comparison of original and resulting images after the paste operation.

What just happened?

Using a combination of Image.crop and Image.paste, we accomplished cropping a region, making some modifications, and then pasting the region back on the image.

Summary

We learned a lot in this article about basic image manipulation.

Specifically, we covered image input-output operations that enable reading and writing of images, and creation of images from scratch. With the help of numerous examples and code snippets, we learned several image manipulation operations. Some of them are:

  • How to resize an image with or without maintaining aspect ratio
  • Rotating or flipping an image
  • Cropping an image, manipulating it using techniques learned earlier in the article, and then pasting it on the original image
  • Creating an image with a text
  • We developed a small application that captures a region of your screen at regular time intervals using ImageGrab.

Further resources on this subject:


About the Author :


Ninad Sathaye

Ninad has more than 6 years of experience in software design and development. He is currently working at IBM India. Prior to IBM, he was a Systems Programmer at Nanorex Inc. based in Michigan, USA. At Nanorex, he was involved in the development of an open source, interactive 3D CAD software, written in Python and C. This is where he developed his passion for the Python programming language. Besides programming, his favorite hobbies are reading and traveling. Ninad holds a Master's of Science degree in Mechanical Engineering from Kansas State University, USA.

Books From Packt


Python 3 Object Oriented Programming
Python 3 Object Oriented Programming

Matplotlib for Python Developers
Matplotlib for Python Developers

Python Testing: Beginner's Guide
Python Testing: Beginner's Guide

Expert Python Programming
Expert Python Programming

Spring Python 1.1
Spring Python 1.1

wxPython 2.8 Application Development Cookbook: RAW
wxPython 2.8 Application Development Cookbook: RAW

Plone 3 Multimedia
Plone 3 Multimedia

Practical Plone 3: A Beginner's Guide to Building Powerful Websites
Practical Plone 3: A Beginner's Guide to Building Powerful Websites


Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software