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)

    The resized images with different filter options appear as follows. Clockwise from left, Image.NEAREST, Image.BILENEAR, Image.BICUBIC, and Image.ANTIALIAS:

  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.

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.