Basic Image Operations

Python Pillow Color Conversions

Image Manipulation

Image Filtering

Image Enhancement and Correction

Image Analysis

Advanced Topics

  • Image Module
  • Python Pillow Useful Resources

    Python Pillow - Quick Guide



    Python Pillow - Overview

    In todays digital world, we come across lots of digital images. In case, we are working with Python programming language, it provides lot of image processing libraries to add image processing capabilities to digital images.

    Some of the most common image processing libraries are: OpenCV, Scikit-image, Pillow, Mahotas and more. However, in this tutorial, we are only focusing on Pillow library and will try to explore various capabilities of this module.

    What is Pillow?

    Pillow or the Python Imaging Library (PIL) fork by Jeffrey A.Clark and contributors, is a powerful Python library for working with digital images and Image processing. It's built on top of the Python Image Library (PIL) and offers a wide range of functionalities for working with images. It provides extensive functionality for opening, manipulating and saving images in various formats. Pillow is a widely used tool in applications involving image processing, computer vision, web development, graphic design and more.

    Pillow offers a wide range of tools and functions for image processing, allowing you to perform tasks such as −

    • Opening and Loading Images − Pillow allows us to open and load images in various formats making them available for processing.
    • Resizing and Scaling − We can resize images to specific dimensions, scale them up or down and generate thumbnails.
    • Cropping − Image cropping involves removing unwanted portions of an image to focus on a specific region.
    • Rotation and Flipping − Images can be rotated to correct orientation or for creative purposes. We can also flip images horizontally or vertically.
    • Color Adjustment − Pillow provides functions to adjust image properties, including brightness, contrast and color balance.
    • Filtering and Effects − Image filtering involves applying filters like blurring, sharpening, edge detection and various effects to enhance or modify the appearance of images.
    • Text and Drawing − We can add text, shapes and drawings to images which is useful for annotation and labeling.
    • Color Mode Conversion − Pillow supports converting images between different color modes such as RGB, grayscale and CMYK.
    • Histogram Equalization − This is a technique for enhancing the contrast of an image by redistributing pixel values.
    • Image Filtering − We can apply custom convolution filters to images allowing for advanced image processing operations.
    • Geometric Transformations − Pillow supports geometric transformations like affine and perspective transformations which are used for tasks such as correcting image distortion.
    • Merging and Compositing − We can merge multiple images or overlay images to create composite images or visual effects.
    • Metadata Handling − Pillow allows us to access and modify image metadata such as EXIF and ICC profiles which can be useful for data extraction and management.
    • Data Access and Analysis − We can access and manipulate pixel data at a low level enabling more advanced image processing and analysis tasks.

    Why Pillow?

    Pillow is a preferred choice for image processing in Python due to its −

    • Image Processing Capabilities − Pillow provides a comprehensive set of tools for image manipulation such as opening, editing, enhancing and saving images. It supports various image formats for making it versatile for handling different types of image data.
    • Ease of Use − Python as a high-level programming language is known for its readability and simplicity. Pillow inherits these characteristics and making it easy for developers to work with images even if they have minimal experience in image processing.
    • Platform Independence − Python is platform-independent and so is Pillow. This means we can use Pillow to process images on different operating systems without worrying about compatibility issues.
    • Abundance of Documentation − Python and Pillow have extensive documentation, tutorials and a supportive community which simplifies the learning curve for newcomers and provides a wealth of resources for experienced developers.
    • Integration with Other Libraries − Python can seamlessly integrate Pillow with other popular libraries and frameworks such as NumPy and OpenCV for advanced image processing and computer vision tasks.
    • Open Source − Both Python and Pillow are open-source which means they are free to use and continually improved by a large community of contributors.

    Example - Opening and Displaying an Image

    Here is a basic example to get you started with Pillow.

    This example demonstrates how to open and display an image in Python Pillow.

    main.py

    from PIL import Image
    
    #Load an image
    loaded_image = Image.open("Images/logo-w.png")
    
    # Display the image
    loaded_image.show()
    

    Output

    overview_ex1

    The above code will load an image from the specified path and display it using the default image viewer on your system.

    Python Pillow - Environment Setup



    To set up the environment for Pillow, it is recommended to use the pip package manager, as it simplifies downloading and installing Python packages. In this chapter, we will cover how to install the Pillow package on your computer.

    Installing Pillow using pip

    To install pillow using pip3, just run the below command in your command prompt −

    pip3 install pillow
    

    In case, if pip and pillow are already installed in your computer, above commands will simply mention the requirement already satisfied as shown below −

    Requirement already satisfied: pillow in .\Lib\site-packages (12.0.0)
    

    How to Install Pillow on MacOS?

    Installing Pillow in a Python environment on macOS is straightforward and can be done using package management tools like pip or conda.

    Follow the below steps to set up Pillow on macOS −

    Open Terminal: We can access the Terminal application on macOS from the Applications folder under Utilities.

    Check Python Version: It's a good practice to ensure we have Python installed. To check our Python version to run the following command −

    py --version
    python 3.14.2
    

    Install 'pip' (if not already installed): Most recent versions of Python come with pip pre-installed. To check if pip is installed we can run −

    pip --version
    pip 26.0
    

    If it's not installed, we can install it by downloading the get-pip.py script and running it with Python. Download the script using curl

    curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
    

    Then run the following script.

    py get-pip.py
    

    Install Pillow: And finally install Pillow using pip by simply run the following command.

    pip3 install Pillow
    

    This command will download and install Pillow and its dependencies.

    Now we have successfully set up the Pillow library in our macOS Python environment. We can now start using Pillow for image processing and manipulation tasks.

    How to Install Pillow on Windows?

    To install the Python Imaging Library (PIL) or its more up-to-date fork on Windows we can follow these steps −

    Install Python: If we haven't already installed Python on our Windows system we can do so by following these steps −

    • Download the latest Python installer for Windows from the official Python website (https://www.python.org/downloads/windows/).

    • Run the installer and during installation and make sure to check the option Add Python X.Y to PATH (replace X.Y with the Python version we are installing).

    Verify Python Installation: Open a command prompt and check that Python has been installed successfully by running the below code −

    py --version
    

    Install Pillow (Recommended): Pillow is the modern fork of PIL and is more actively maintained. To install Pillow open a command prompt and run the following command −

    pip3 install Pillow
    

    This command will download and install Pillow and its dependencies on our Windows system.

    How to Install Pillow on Linux?

    Setting up the Pillow library in a Python environment on a Linux-based operating system is similar to the process on macOS. Here are the steps for setting up the environment for Pillow on Linux.

    Check Python Installation: Most Linux distributions come with Python pre-installed. To check if Python is installed first open the terminal and run the following code.

    py --version
    

    Make sure we have Python 3.x installed as Python 2 is no longer supported.

    Install 'pip' (if not already installed): Most recent versions of Python come with pip pre-installed. To check if pip is installed, run the following code.

    pip3 --version
    

    If it's not installed we can install it using the package manager specific to our Linux distribution. For example on Debian/Ubuntu-based systems run the following commands based on the OS.

    sudo apt-get install python3-pip
    

    On Red Hat/CentOS-based systems

    sudo yum install python3-pip
    

    Install Pillow: To install Pillow using pip and run the below command −

    pip3 install Pillow
    

    This command will download and install Pillow and its dependencies.

    Example - Verifying Installation

    To verify that Pillow has been successfully installed in our system, we can create a Python script and import the library −

    main.py

    from PIL import Image
    
    #Create an Image object
    img = Image.new('RGB', (100, 100), color='blue')
    
    #Display the image
    img.show()
    

    Output

    blue color

    Save the script with a .py extension and execute it using Python. If Pillow is installed correctly an image window displaying a red square should appear.

    Virtual Environment (Optional but Recommended)

    It's a good practice to create a virtual environment for our Python projects to keep dependencies isolated. We can create a virtual environment using the following command −

    py -m venv myenv
    

    Replace myenv with the name we want for our virtual environment. To activate the virtual environment run the below code −

    source myenv/bin/activate
    

    Now we can use our virtual environment to work on Python projects that require Pillow.

    Python Pillow - Working With Images



    Opening, writing, displaying and saving images are the fundamental operations while working with images using python pillow library. The Python Pillow library provides a wide range of tools for image processing tasks, providing straightforward methods and customizable options for these basic operations.

    In this tutorial, you will lean essential aspects of working with images using the Pillow library including reading, displaying,writting, and saving images.

    Reading Images

    Reading images, refers to the process of opening and reading image files and making them accessible for manipulation and processing within a Python program.

    In Pillow the Image module provides the function open() to perform loading of the given input image. When we call Image.open() it reads the specified image file, decodes the image and creates a Pillow Image object representing the image. This object can then be used for various image processing tasks.

    Reading images using open() function

    The Image.open() function is capable of loading different image formats such as JPEG, PNG, GIF, BMP, TIFF, ICO and so on.

    The below is the syntax and parameters of this function.

    PIL.Image.open(fp, mode='r', formats = None)
    

    Where,

    • fp − A filename or path or URL of an image within the string format.

    • mode (optional) − The mode parameter is used to set the image into open mode and it should be assigned as r.

    • formats (optional) − A list or tuple of formats which to be loaded. This can be used as the restriction of the file formats to be loaded.

    This function returns the image as the output. Here for displaying the image we have to use the show() function of the Image module.

    Example - Loading an Image

    In this example we are loading an image by specifying the path of the image in the string format and defining the mode as r.

    main.py

    from PIL import Image
    
    #Load an image
    loaded_image = Image.open("Images/butterfly.jpg", mode = 'r')
    loaded_image.show()
    
    #Saving the image
    loaded_image.save("Output_Images/reading.png")
    

    Image to be used

    butterfly

    Output

    reading

    Example - Loading Image using URL

    In this example we are loading the image from the image url. So to perform that we have to use urllib.request() module for reading the image url.

    We use the urlretrieve() function of the urllib.request module to download the image from the URL and save it to the local filesystem with the specified filename.

    main.py

    import urllib.request
    from PIL import Image
    url = "https://www.tutorialspoint.com/images/logo.png"
    
    #Download the image using urllib
    urllib.request.urlretrieve(url, "image.png")
    
    #Open the downloaded image in PIL
    loading_image = Image.open("image.png", mode = 'r')
    
    #Show the image
    loading_image.show()
    

    Output

     tutorialpoint logo

    Example - Loading Image without format

    In this example we are passing the image name and the formats = None as the input parameters.

    from PIL import Image
    
    #load the image
    loading_image = Image.open("Images/pillow.jpg", formats = None)
    
    #Show the image
    loading_image.show()
    

    Output

     pillow

    Writing Images

    Writing images are nothing but creating new image files from scratch or modifying existing ones such as drawing, pixel manipulation and compositing. The resulting image can then be further processed or saved to disk using other Pillow functions and methods.

    Writing images using new() method

    You can use the new() method from the Image module to create a blank image with a specified mode and size. It's a way to generate a blank or uninitialized image with the desired characteristics.

    The following is the syntax for Image.new()

    PIL.Image.new(mode, size, color)
    

    Where,

    • mode − This parameter specifies the color mode for the image such as "RGB" for full-color images or "L" for grayscale. The available modes depend on the version of Pillow and the capabilities of the underlying image libraries (e.g., "RGB," "RGBA," "L," "CMYK," etc.).

    • size − This parameter is a tuple specifying the width and height of the image in pixels. For example to create a 300x200-pixel image we can use '(300, 200)'.

    • color' (optional) − This parameter specifies the initial color of the image. It's an optional parameter and can be a single color value or a tuple for multi-channel images. The default color is black for most modes.

    Example - Creating Image

    In this example we are creating a new image with black using the new() method in Image module in pillow library.

    from PIL import Image
    
    #Create a new 300x200 pixel RGB image filled with white
    img = Image.new('RGB', (300, 200), color='black')
    img.show()
    

    Output

    writing img

    Example - Creating Blue Box

    Here, in this example we are creating a new image with blue color of width 600 and height 600 using the new() method in Image module of the pillow.

    main.py

    from PIL import Image
    
    #Create a new 300x200 pixel RGB image filled with white
    img = Image.new('RGB', (500, 200), color='blue')
    img.show()
    

    Output

    writing new

    Displaying Image

    Displaying images is about rendering the image on the screen so you can view it. Pillow provides the show() method to display an image using the default image viewer of the system.

    Displaying images using the show() method

    The show() method in Image module does not require any parameters or arguments. This is a straightforward.

    Syntax

    The below is the syntax of show() function −

    PIL.Image.show()
    

    Example - Displaying Image

    In this example we are displaying the output of the open() function using the show() function of Image module.

    main.py

    from PIL import Image
    
    #Open an image
    image = Image.open("Images/handwriting.jpg")
    
    #Display the image using the default image viewer
    image.show()
    

    Output

    handwriting

    Example - Displaying Images in the Jupyter Notebook Environment

    If we are working in a Jupyter Notebook environment then we can display images directly in the notebook using the IPython display() function.

    The following is the syntax and parameters of the display() function −

    IPython.display.display(image_name)
    

    Where,

    • image_name − This is the name of the image to be displayed.

    Example - Displaying Image in Notebook

    In this example we are displaying the image using the display() function of the IPython.display module.

    from PIL import Image
    from IPython.display import display
    
    #Load the image
    loading_image = Image.open("Images/tutorialspoint.png")
    
    #Show the image
    display(loading_image)
    

    Output

    tutorialspoint

    Example - Displaying in a GUI Application

    If we are building a graphical user interface (GUI) application then we can use a GUI toolkit like Tkinter for desktop applications or a web framework like Flask or Django for web applications to display images in the user interface.

    main.py

    In this example we are using the ImageTk method of the PIL module to display the image output.

    import tkinter as tk
    from PIL import Image, ImageTk
    
    def display_image(image_path):
       root = tk.Tk()
       root.title("Image Viewer")
       
       image = Image.open(image_path)
       photo = ImageTk.PhotoImage(image)
       
       label = tk.Label(root, image=photo)
       label.image = photo
       label.pack()
       
       root.mainloop()
    
    display_image("Images/tutorialspoint.png")
    

    Output

    image viewer

    Saving Images

    Saving images in pillow refers to save the opened image into the memory and making them accessible for manipulation and processing within a Python program.

    The Image module of the pillow library provides the save() method, allowing you to to save the specified image object into the specified location of the memory or local system.

    Saving images using save() function

    The save() method allow us to save the opened image in different file formats such as JPG, PNG, PDF and so on. This function specifies various options for saving the image including the format, quality and other parameters.

    The following is the syntax and parameters of this function.

    PIL.Image.save(file, format=None, **params)
    

    Where,

    • file − The file path or a file-like object to which the image will be saved.

    • format(optional) − The format to save the image in. If not specified Pillow will try to determine the format from the file extension.

    • params(optional) − Additional parameters that depend on the format we are saving the image in.

    This function saves the image in the specified location with the specified file name.

    Example - Saving Image

    In this example we are opening the specified image using the open() function of the Image module of pillow library. Then saving the opened image in the specified location by passing the path as the input parameter to the save() function.

    main.py

    from PIL import Image
    loading_image = Image.open("pillow.jpg")
    
    #Show the image
    loading_image.show()
    
    #Save the image
    loading_image.save("Images/saved_image.jpg")
    print("Image saved")
    

    Output

    Loaded Image −

    pillow

    Saved Image −

    saved image

    Example - Using various parameters

    Here in this example are using the other optional parameters for saving the image in the specified location.

    main.py

    from PIL import Image
    #Load the image
    loading_image = Image.open("Images/tutorialspoint.png")
    
    #Show the image
    loading_image.show()
    
    #Save the image
    loading_image.save("Output_Images/save_outputimg.png", format = "PNG", quality = 200)
    print("Image saved")
    

    Output

    Loaded Image −

    loaded image

    Saved Image −

    save images

    We can use the save() method to save images in various formats and control the quality and other format-specific options as needed for our specific use case.

    Python Pillow - Resizing an Image



    Resizing an image in Pillow Library involves changing the dimensions i.e. width and height of the image. This operation can be used to make an image larger or smaller and it can serve various purposes such as preparing images for display on a website, reducing file size or generating thumbnails.

    Resizing an Image using the resize() method

    In Pillow the resize() method is used to change the dimensions of an image. This function allows us to resize an image in the following ways.

    • Absolute Dimensions − We can specify the new width and height in pixels to which the image should be resized.

    • Maintaining Aspect Ratio − If We only specify one dimension either width or height then Pillow can automatically calculate the other dimension to maintain the image's aspect ratio.

    • Scaling − We can resize the image by a scale factor which uniformly resizes both width and height while preserving the aspect ratio.

    Here's the basic syntax for the resize() method −

    PIL.Image.resize(size, resample=3)
    

    Where,

    • size − This can be either a tuple specifying the new width and height in pixels i.e. a single integer specifying the new size (width or height) or a float specifying a scaling factor.

    • resample(optional) − The default value is 3 which corresponds to the anti-aliased high-quality filter. We can choose from various resampling filters such as Image.NEAREST, Image.BOX, Image.BILINEAR, Image.HAMMING, Image.BICUBIC, Image.LANCZOS, etc.

    Following is the input image used in all the examples of this chapter.

    flower

    Example - Resizing an Image

    In this example we are using the resize() function for adjusting the width and height of the image by passing a tuple as input parameter.

    main.py

    from PIL import Image
    
    #Open an image
    image = Image.open("Images/rose.jpg")
    
    #Resize to specific dimensions (e.g., 300x200 pixels)
    new_size = (300, 200)
    resized_image = image.resize(new_size)
    
    #Display resized image
    resized_image.show()
    

    Output

    flower image

    Example - Resizing an Image with maintaining Aspect Ratio

    Here in this example we are resizing the image by maintaining the same aspect ratio of the original input image.

    from PIL import Image
    
    #Open an image
    image = Image.open("Images/rose.jpg")
    
    #Resize by maintaining aspect ratio (e.g., specify the width)
    new_width = 200
    aspect_ratio_preserved = image.resize((new_width, int(image.height * (new_width / image.width))))
    aspect_ratio_preserved.show()
    

    Output

    flower resized

    Example - Resizing with Scale Factor

    In this example we are resizing the image with the scale by factor.

    main.py

    from PIL import Image
    
    #Open an image
    image = Image.open("Images/rose.jpg")
    
    #Scale the image by a factor (e.g., 10% of the original size)
    scaling_factor = 0.1
    scaled_image = image.resize((int(image.width * scaling_factor), int(image.height * scaling_factor)))
    scaled_image.show()
    

    Output

    flower output

    Python Pillow - Flip and Rotate an Image



    Flipping and rotating images are basic image processing tasks often used to enhance visibility, correct orientation, or achieve specific effects. The Python Pillow library provides simple methods to perform these operations on images.

    Flipping images

    Flipping an image is an image processing operation that involves reversing the orientation of the image along a specified axis. This operation can be performed either horizontally i.e. left to right or vertically i.e. top to bottom. In digital image processing flipping is often used for various purposes such as mirroring, correcting for camera orientation or achieving artistic effects.

    In the context of image flipping there are two primary types, one is horizontal flip and other is vertical flip.

    • Horizontal Flip (Left to Right) − In a horizontal flip each row of pixels is reversed effectively mirroring the image from left to right.

    • Vertical Flip (Top to Bottom) − In a vertical flip each column of pixels is reversed effectively mirroring the image from top to bottom.

    These can be achieved by using the transpose() method of the Image module of the pillow library.

    Flipping images using the transpose() method

    The transpose() method in Pillow is used to manipulate the orientation of an image. It allows us to perform various transformations on the image such as rotating and mirroring by specifying the type of transpose operation we want to apply.

    The following is the syntax and parameters of the transpose() method.

    PIL.Image.transpose(method)
    

    Where,

    • method − The transpose method to be applied. It can take one of the following values −

      • Image.Transpose.ROTATE_90 − Rotate the image 90 degrees counterclockwise.

      • Image.Transpose.ROTATE_180 − Rotate the image 180 degrees.

      • Image.Transpose.ROTATE_270 − Rotate the image 90 degrees clockwise.

      • Image.Transpose.FLIP_LEFT_RIGHT − Flip the image horizontally i.e. left to right.

      • Image.Transpose.FLIP_TOP_BOTTOM − Flip the image vertically i.e. top to bottom.

    Following is the input image used in all the examples of this chapter.

    python_programming

    Example - Rotating Image

    In this example we are using the transpose() method to flip the input image by 90 degrees counterclockwise.

    from PIL import Image
    
    #Open an image
    image = Image.open("Images/python_programming.jpg")
    
    #Rotate the image 90 degrees counterclockwise
    rotated_image = image.transpose(Image.Transpose.ROTATE_90)
    
    #Save or display the rotated image
    rotated_image.save("Output_images/rotated_image.jpg")
    open_rotated_image = Image.open("Output_images/rotated_image.jpg")
    open_rotated_image.show()
    

    Output

    flipping

    Example - Flipping Image

    In this example we are using the transpose() method to flip the input image by horizontally.

    from PIL import Image
    
    #Open an image
    image = Image.open("Images/python_programming.jpg")
    
    #Flip the image horizontally (left to right)
    flipped_image = image.transpose(Image.Transpose.FLIP_LEFT_RIGHT)
    
    #Save or display the rotated image
    flipped_image.save("Output_images/flipped_image.jpg")
    open_flipped_image = Image.open("Output_images/flipped_image.jpg")
    open_flipped_image.show() 
    

    Output

    flipping horizontally

    Example - Flipping Top Bottom

    In this example we are using the transpose() method by using FLIP_TOP_BOTTOM parameter to flip the input image by vertically.

    from PIL import Image
    
    #Open an image
    image = Image.open("Images/python_programming.jpg")
    
    #Flip the image horizontally (left to right)
    vflipped_image = image.transpose(Image.Transpose.FLIP_TOP_BOTTOM)
    
    #Save or display the rotated image
    vflipped_image.save("Output_images/vflipped_image.jpg")
    open_flipped_image = Image.open("Output_images/vflipped_image.jpg")
    open_flipped_image.show()
    

    Output

    flipping right

    Rotating Images

    Rotating an image in Pillow (Python Imaging Library) refers to the process of changing the orientation of an image by a specific angle. This can be useful for various purposes such as correcting the orientation of photos, creating special effects or aligning images.

    Pillow provides the rotate() method to perform this operation. The below are the points we need to know about rotating images in Pillow.

    • Rotate by Angle − The rotate() method allows us to specify the angle in degrees by which we want to rotate the image. A positive angle rotates the image counterclockwise and a negative angle rotates it clockwise.

    • Canvas Expansion − By default when we rotate an image it may not fit entirely within the original image canvas and which can lead to cropping. Then we can use the expand parameter to ensure that the rotated image fits within the canvas without being cropped.

    Rotating images using the rotate() method

    The rotate() method in Image module is used to perform rotation of the given input image.

    Here the following is the basic syntax of the rotate() method.

    PIL.Image.rotate(angle, expand=False, resample=3)
    

    Where,

    • angle − This parameter specifies the angle of rotation in degrees. Positive values rotate the image counterclockwise while negative values rotate it clockwise.

    • expand (optional) − If it is set to True it allows the image canvas to be expanded to ensure that the entire rotated image fits within it. If it is set to 'False' (the default) the image is cropped to fit within the original canvas.

    • resample (optional) − An optional resampling filter. The default value is '3' which corresponds to the anti-aliased high-quality filter. We can choose from various resampling filters such as 'Image.NEAREST', 'Image.BOX', 'Image.BILINEAR', 'Image.HAMMING', 'Image.BICUBIC', 'Image.LANCZOS', etc.

    Following is the input image used in all the examples of this chapter.

    flowers

    Example - Rotating Image

    In this example we are using the rotate() method for rotating the given input image by 45 degrees.

    from PIL import Image
    
    #Open an image
    image = Image.open("Images/rose.jpg")
    
    #Rotate the image by 45 degrees counterclockwise
    rotated_image = image.rotate(45)
    
    #Save the rotated image
    rotated_image.save("Output_images/output.jpg")
    rotated_image.show()
    

    Output

    rotate

    Example - Rotating Image without cropping

    Here in this example we are rotating the input image by ensuring the rotated image fits within the canvas without cropping. This can be achieved by setting the expand parameter to True.

    from PIL import Image
    
    #Open an image
    image = Image.open("Images/rose.jpg")
    
    #Rotate the image by 45 degrees and expand the canvas to fit the entire rotated image
    rotated_image = image.rotate(45, expand=True)
    rotated_image.show()
    

    Output

    rotate flower

    Example - Rotating Anticlockwise

    In this example we are rotating the image into anticlockwise by passing negative value -45 degrees as parameter to the rotate() method.

    from PIL import Image
    
    #Open an image
    image = Image.open("Images/rose.jpg")
    
    #Rotate the image by 45 degrees and expand the canvas to fit the entire rotated image
    rotated_image = image.rotate(-45, expand=True)
    rotated_image.show()
    

    Output

    rotate anticlockwise

    Python Pillow - Cropping an Image



    Cropping an image in Pillow (Python Imaging Library) involves selecting a specific region or subarea of an image and creating a new image from that region. This operation is useful for removing unwanted parts of an image and focusing on a particular subject or resizing an image to specific dimensions.

    The Image module of the pillow library provides the crop() method to perform the crop operation on the images.

    Cropping an Image using the crop() method

    Cropping an image can be done by using the crop() method, which allows us to define a box specifying the coordinates of the left, upper, right and lower corners of the region that we want to retain and then it creates a new image with only that portion of the original image.

    Here is the basic syntax for the crop() method in Pillow library −

    PIL.Image.crop(box)
    

    Where,

    • box − A tuple specifying the coordinates of the cropping box in the format (left, upper, right, lower). These coordinates represent the left, upper, right and lower edges of the rectangular region we want to retain.

    Example - Cropping an Image

    In this example we are cropping the image by using the crop() method by passing the left, upper, right and lower corners of the image region that we want.

    main.py

    from PIL import Image
    
    #Open an image
    image = Image.open("Images/saved_image.jpg")
    
    # Display the inaput image 
    image.show()
    
    #Define the coordinates for the region to be cropped (left, upper, right, lower)
    left = 100  
    upper = 50  
    right = 300  
    lower = 250 
    
    #Crop the image using the coordinates
    cropped_image = image.crop((left, upper, right, lower))
    
    #Display the cropped image as a new file
    cropped_image.show()
    

    Output

    The above code will generate the following output −

    Input image:

    crop_image_input

    Output image cropped image:

    crop_output image

    Example - Cropping a Specific Portion of an Image

    Here this is another example of performing the crop operation of the specified portion of the input image using the crop() method.

    main.py

    from PIL import Image
    
    #Open an image
    image = Image.open("Images/yellow_car.jpg")
    
    # Display the inaput image 
    image.show()
    
    #Define the coordinates for the region to be cropped (left, upper, right, lower)
    left = 100  
    upper = 100  
    right = 300  
    lower = 300 
    
    #Crop the image using the coordinates
    cropped_image = image.crop((left, upper, right, lower))
    
    #Display the cropped image 
    cropped_image.show()
    

    Output

    On executing the above code you will get the following output −

    Input image:

    crop_image_input

    Output cropped image:

    crop_output image

    Python Pillow - Adding Borders to an Image



    Adding borders to images is one of the common task in image processing. Borders can help to frame the content, draw attention to specific areas, or add a decorative element. In Pillow (PIL) the expand() method of the ImageOps module is used to increase the dimensions of an image by adding a border or padding around it. This can be helpful for various purposes such as adding a border, creating a canvas of a specific size or resizing the image to fit a particular aspect ratio.

    The expand() method

    The expand() method is useful for adding borders to images and adjusting their dimensions while maintaining the aspect ratio. We can customize the size and border color to suit our specific requirements.

    Here's the basic syntax for the expand() method −

    PIL.Image.expand(size, fill=None)
    

    Where,

    • size − A tuple specifying the new dimensions i.e. width and height for the expanded image.

    • fill (optional) − An optional color value to fill the border area. It should be specified as a color tuple (R, G, B) or an integer value representing the color.

    Following is the input image used in all the examples of this chapter.

    expanded image

    Example - Expanded Image with Border

    In this example we are using the expand() method to create the expanded image with the border.

    from PIL import Image, ImageOps
    
    #Open an image
    image = Image.open("Images/handwriting.jpg")
    
    #Define the new dimensions for the expanded image
    new_width = image.width + 40  
    #Add 40 pixels to the width
    new_height = image.height + 40  
    #Add 40 pixels to the height
    
    #Expand the image with a white border
    expanded_image = ImageOps.expand(image, border=20, fill="red")
    
    #Save or display the expanded image
    expanded_image.save("Output_Images/expanded_output.jpg")
    open_expand = Image.open("Output_Images/expanded_output.jpg")
    open_expand.show()
    

    Output

    image with red border

    Example - Expanding Image with Blue Border

    Here this is another example we are expanding the image border with blue color by using the expand() method of the Image module.

    main.py

    from PIL import Image, ImageOps
    
    #Open an image
    image = Image.open("Images/handwriting.jpg")
    
    #Define the new dimensions for the expanded image
    new_width = image.width + 40  
    #Add 40 pixels to the width
    new_height = image.height + 40  
    #Add 40 pixels to the height
    
    #Expand the image with a white border
    expanded_image = ImageOps.expand(image, border=100, fill="blue")
    
    #Save or display the expanded image
    expanded_image.save("Output_Images/expanded_output.jpg")
    open_expand = Image.open("Output_Images/expanded_output.jpg")
    open_expand.show()
    

    Output

    image with blue border

    Python Pillow - Identifying an Image File



    Identifying image files using the Python Pillow (PIL) library involves checking file extensions to determine if a file is likely an image or not. While Pillow itself doesn't have a built-in method to identify image files and we can use functions of os module such as listdir(), path.splitext(), path.is_image_file(), path.join() to filter files based on their extensions as per our user requirements.

    Python's os.path module does not provide a direct is_image_file() function for identifying image files. Instead we can typically use the Pillow library (PIL) to check if a file is an image.

    However we can create a custom is_image_file() function using os.path in combination with Pillow to check if a file appears to be an image based on its extension.

    Here's an example of how we can use os.path to check file extensions and determine if a file is likely an image file −

    • We define the is_image_file() function which first checks if the file's extension appears to be a common image format (defined in 'image_extensions'). If the file extension is not recognized, it's assumed not to be an image file.

    • For recognized image file extensions the function attempts to open the file as an image using Pillow's Image.open(). If this operation succeeds without errors then the function returns True indicating that the file is a valid image.

    • If there is an issue opening the file the function returns False.

    • This approach combines os.path for extracting file extensions and Pillow for checking whether the file is a valid image.

    Example - Idetifying an Image file

    main.py

    import os
    from PIL import Image
    
    def is_image_file(file_path):
       image_extensions = {".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tiff", ".ico"}  
       #Add more extensions as needed
       _, file_extension = os.path.splitext(file_path)
     
       #Check if the file extension is in the set of image extensions
       return file_extension.lower() in image_extensions
    
    file_path = "Images/butterfly.jpg"
    if is_image_file(file_path):
       print("This is an image file.")
       Image.open(file_path)
    else:	
       print("This is not an image file.")
    

    Output

    This is an image file.
    

    Example - Checking PDF file as Image File

    In this example we are passing the file extension as pdf, as it is not a image file extension the result will be not a image file.

    main.py

    import os
    from PIL import Image
    
    def is_image_file(file_path):
       image_extensions = {".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tiff", ".ico"}  
       #Add more extensions as needed
       _, file_extension = os.path.splitext(file_path)
     
       #Check if the file extension is in the set of image extensions
       return file_extension.lower() in image_extensions
    
    file_path = "Images/butterfly.pdf"
    if is_image_file(file_path):
       print("This is an image file.")
       Image.open(file_path)
    else:	
       print("This is not an image file.")
    

    Output

    This is not an image file.
    

    Python Pillow - Merging Images



    Pillow (PIL) library is used for merging or combining individual bands of an image to create a new multiband image. It's particularly useful when working with multispectral or multichannel images such as RGB or CMYK images and we want to create a new image by merging specific bands.

    In pillow we have the merge() method which belongs to the Image module which is used to merge the given input images.

    This method is useful for tasks like combining multiple channels of satellite or medical images, creating custom color images or working with images that have separate channels that need to be combined into a single image.

    Syntax

    Here's the syntax and usage of the Image.merge() method −

    Image.merge(mode, bands)
    

    Where,

    • mode − This parameter specifies the mode of the new multiband image. It should match the mode of the individual bands we want to merge. Common modes include "RGB" for color images, "RGBA" for images with an alpha channel, and "CMYK" for cyan, magenta, yellow and black color spaces.

    • bands − This parameter is a tuple of individual image bands that we want to merge. Each band should be a single-channel image or a grayscale image.

    Example - Merging Image with RGB Bands

    Here is an example of how to use the Image.merge() method to merge the red, green and blue bands of an image to create a new RGB image.

    main.py

    from PIL import Image
    
    image = Image.open("Images/butterfly.jpg")
    r, g, b = image.split()
    image = Image.merge("RGB", (b, g, r))
    image.show()
    

    Image to be used

    butterfly original image

    Output

    blue butterfly

    Example - Merging Images

    Here, in this example we are merging two input images by using the merge() method of the Image module of pillow library.

    from PIL import Image
    image1 = Image.open("Images/butterfly.jpg")
    image2 = Image.open("Images/handwriting.jpg")
    
    #resize, first image
    image1 = image1.resize((426, 240))
    image1_size = image1.size
    image2_size = image2.size
    new_image = Image.new("RGB",(2*image1_size[0], image1_size[1]), (250,250,250))
    new_image.paste(image1,(0,0))
    new_image.paste(image2,(image1_size[0],1))
    new_image.save("Output_Images/merged.jpg")
    new_image.show()
    

    The two images to be merged

    butterfly original image expanded image

    Output

    two images merged

    Python Pillow - Cut and Paste Image



    Cutting Images

    Pillow (Python Imaging Library) allows us to extract a rectangular region from an image. The extracted region of the image is also known as a bounding box from an image. In The crop() method of the Image module creates a new image that represents the specified region of the original image. This method allows us to specify the coordinates of the bounding box for the region we want to crop.

    Here is the syntax and usage of the 'crop()' method in Pillow −

    Image.crop(box)
    

    Where,

    • box − This is a tuple specifying the rectangular region we want to extract. The box parameter should be a tuple of four values: (left, upper, right, lower).

      • left is the x-coordinate of the left edge of the bounding box.

      • upper is the y-coordinate of the upper edge of the bounding box.

      • right is the x-coordinate of the right edge of the bounding box.

      • lower is the y-coordinate of the lower edge of the bounding box.

    Example - Cutting a Rectangular Portion from an Image

    In this example we are cropping a rectangular portion as per our requirement using the crop() method of the Image module.

    main.py

    from PIL import Image
    
    #Open the image
    image = Image.open("Images/book.jpg")
    
    #Define the bounding box for cropping
    box = (100, 100, 200, 200)  
    #(left, upper, right, lower)
    
    #Crop the image using the defined bounding box
    cropped_image = image.crop(box)
    
    #Save or display the cropped image
    cropped_image.save("Output_Images/cropped_image.jpg")
    cropped_image.show()
    

    Image to be cropped

    book

    Output

    cropped image

    Example - Cutting another Image

    Here this is another example for cropping a rectangular part of the image by using the crop() method.

    main.py

    from PIL import Image
    
    #Open the image
    image = Image.open("Images/rose.jpg")
    
    #Define the bounding box for cropping
    box = (10, 10, 200, 200)  
    #(left, upper, right, lower)
    
    #Crop the image using the defined bounding box
    cropped_image = image.crop(box)
    
    #Save or display the cropped image
    cropped_image.save("Output_Images/cropped_image.jpg")
    cropped_image.show()
    

    Input Image

    flower

    Output

    cropped_image

    Pasting Images

    Pasting images using Python Pillow allows us to extract a region of interest from one image and paste it onto another. This process is useful for tasks like image cropping, object extraction and compositing.

    The paste() method in Pillow (Python Imaging Library) allows us to paste one image onto another at a specified position. It's a commonly used method for compositing images, adding watermarks or overlaying one image on top of another.

    The below is the syntax and parameters of the paste() function −

    PIL.Image.paste(im, box, mask=None)
    
    • im − This is the source image i.e., the image we want to paste onto the current image.

    • box − This parameter specifies the position where we want to paste the source image. It can be a tuple of coordinates '(left, upper, right, lower)'. The source image will be pasted inside the bounding box defined by these coordinates.

    • mask (optional) − If this parameter provided then it can be an image that defines a transparency mask. The pasted image will be masked according to the transparency values in the mask image.

    Example - Pasting an Image

    Here is an example of how to use the paste() method to paste one image onto another.

    main.py

    from PIL import Image
    
    #Open the background image
    background = Image.open("Images/black_white.jpg")
    
    #Open the image to be pasted
    image_to_paste = Image.open("Images/tutorialspoint.jpg")
    
    #Define the position where the image should be pasted
    position = (100, 100)
    
    #Paste the image onto the background
    background.paste(image_to_paste, position)
    
    #Save the modified image
    background.save("Output_Images/paste1.jpg")
    background.show()
    

    Images to be used

    black white tutorialpoint

    Output

    paste1

    Python Pillow - Rolling an Image



    Pillow (Python Imaging Library) allows us to roll or shift the image's pixel data within the image. This operation moves the pixel data either horizontally (left or right) or vertically (up or down) to create a rolling effect.

    There is no direct method in pillow to roll or shift the image pixel data but it can be performed by using the copy and paste operations on the image. The below are the steps to be followed to perform rolling of the image.

    • Import the necessary modules.

    • Next load the image that we want to roll.

    • Define the rolling offset

      The rolling offset determines how much we want to shift the image. A positive value for the offset will shift the image right i.e. horizontal rolling or down i.e. vertical rolling and a negative value will shift the image left or up. We can choose the offset value based on our desired rolling effect.

    • Create a new image with the same size as the original. This new image will serve as the canvas for the rolled result.

    • Perform the rolling operations i.e. either horizontal rolling or vertical rolling.

    • Save the rolled image to a file.

    • Optionally display the rolled image. This step is useful for visualizing the result but it's not necessary.

    Following is the input image used in all the examples of this chapter.

    flowers

    Example - Horizontally Rolling an Image

    In this example we are performing the horizontal rolling on the input image by specifying the horizontal offset as 50.

    main.py

    from PIL import Image
    image = Image.open("Images/flowers.jpg")
    horizontal_offset = 50  
    #Change this value as needed
    rolled_image = Image.new("RGB", image.size)
    for y in range(image.height):
       for x in range(image.width):
          new_x = (x + horizontal_offset) % image.width
          pixel = image.getpixel((x, y))
          rolled_image.putpixel((new_x, y), pixel)
    rolled_image.save("Output_Images/horizontal_rolled_image.jpg")
    rolled_image.show()
    

    Output

    horizontal rolled image

    Example - Vertically Rolling an Image

    In this example we are rolling the image vertically by specifying the offset value as 50.

    main.py

    from PIL import Image
    image = Image.open("Images/flowers.jpg")
    vertical_offset = 50  
    #Change this value as needed
    rolled_image = Image.new("RGB", image.size)
    for x in range(image.width):
       for y in range(image.height):
          new_y = (y + vertical_offset) % image.height
          pixel = image.getpixel((x, y))
          rolled_image.putpixel((x, new_y), pixel)
    rolled_image.save("Output_Images/vertical_rolled_image.jpg")
    rolled_image.show()
    

    Output

    vertical rolled image

    Python Pillow - Writing Text to an Image



    Adding text to images is a common image processing task that involves overlaying text onto an image. This can be done for various purposes such as adding captions, labels, watermarks or annotations to images. When adding text to images we can typically specify the text content, font, size, color and position.

    In Pillow (PIL) We can use the text() method from the ImageDraw module to add text to an image.

    The text() method

    The text() method allows us to specify the position, text content, font and color of the text we want to add.

    Syntax

    The below is the basic syntax and parameters for using the text() method −

    PIL.ImageDraw.Draw.text(xy, text, fill=None, font=None, anchor=None, spacing=0, align="left")
    
    • xy − The position where the text should be placed. It should be a tuple '(x, y)' representing the coordinates.

    • text − The text content that we want to add to the image.

    • fill (optional) − The color of the text. It can be specified as a tuple '(R, G, B)' for RGB colors a single integer for grayscale colors or as a named color.

    • font (optional) − The font to use for the text. We can specify the font using 'ImageFont.truetype()' or 'ImageFont.load()'.

    • anchor (optional) − Specifies how the text should be anchored. Options include "left", "center", "right", "top", "middle" and "bottom".

    • spacing (optional) − Specifies the spacing between lines of text. Use positive values to increase spacing or negative values to reduce spacing.

    • align (optional) − Specifies the horizontal alignment of the text within the bounding box. Options include "left", "center" and "right".

    Following is the input image used in all the examples of this chapter.

    book

    Example - Writing a Text to an Image

    In this example we are adding the text Tutorialspointto the input image using the text() method of the Image module.

    main.py

    from PIL import Image, ImageDraw, ImageFont
    
    #Open an image
    image = Image.open("Images/book.jpg")
    
    #Create a drawing object
    draw = ImageDraw.Draw(image)
    
    #Define text attributes
    text = "Tutorialspoint"
    font = ImageFont.truetype("arial.ttf", size=30)
    text_color = (255, 0, 0)  
    #Red
    position = (50, 50)
    
    #Add text to the image
    draw.text(position, text, fill=text_color, font=font)
    
    #Save or display the image with the added text
    image.save("Output_Images/textoutput.jpg")
    opentext = Image.open("Output_Images/textoutput.jpg")
    opentext.show()
    

    Output

    textoutput

    Example - Writing another text to an Image

    Here this is another example of adding text to the image by using the text() method of the ImageDraw module.

    main.py

    from PIL import Image, ImageDraw, ImageFont
    
    #Open an image
    image = Image.open("Images/book.jpg")
    
    #Create a drawing object
    draw = ImageDraw.Draw(image)
    
    #Define text attributes
    text = "Have a Happy learning"
    font = ImageFont.truetype("arial.ttf", size=10)
    text_color = (255, 0, 255)  
    position = (150, 100)
    
    #Add text to the image
    draw.text(position, text, fill=text_color, font=font)
    
    #Save or display the image with the added text
    image.save("Output_Images/textoutput.jpg")
    opentext = Image.open("Output_Images/textoutput.jpg")
    opentext.show()
    

    Output

    textoutput

    Python Pillow - ImageDraw Module



    Drawing on images in Pillow involves using the Pillow library (Python Imaging Library) to add various visual elements such as lines, shapes, text and more to an existing image. This is a common image processing task used for tasks like image annotation, creating visualizations, adding labels or captions highlighting areas of interest and more.

    We can use the ImageDraw module in Pillow to create a drawing object and then use various methods of this object to draw on the image. We can use the line(), rectangle(), ellipse(), text() and other methods to draw various elements on the image.

    Drawing Text on the Image

    To draw or write text on an image we can use the ImageDraw.Draw() function in the Pillow library, this method creates a drawing object that allows us to perform drawing operations on images.

    Syntax

    The following is the syntax and parameters of the Draw() method −

    PIL.ImageDraw.Draw(image, mode=None)
    

    Where,

    • image − This parameter represents the image on which we want to perform drawing operations. It's an instance of a Pillow Image object.

    • mode (optional) − This parameter specifies the mode in which drawing will occur. The available modes are −

      • 1 − 1-bit pixels (monochrome)
      • L − 8-bit pixels, black and white
      • RGB − 3x8-bit pixels, true color
      • RGBA − 4x8-bit pixels with transparency
      • CMYK − 4x8-bit pixels in the CMYK color space
      • HSV − 3x8-bit pixels in the HSV color space

    Input image to be used for the below two examples.

    faces

    Example - Using Draw() method to add Text to Image

    In this example we are using the Draw() method of the ImageDraw module to add text on the image.

    main.py

    from PIL import Image, ImageDraw, ImageFont
    
    #Open an image
    image = Image.open("Images/faces.jpg")
    
    #Create a drawing object
    draw = ImageDraw.Draw(image)
    
    #Define text attributes
    text = "Welcome to Tutorialspoint"
    font = ImageFont.truetype("arial.ttf", size=30)
    text_color = (0, 0, 255)  
    
    #Blue
    text_position = (50, 50)
    
    #Add text to the image
    draw.text(text_position, text, fill=text_color, font=font)
    
    #Save or display the image with the added drawing elements
    image.save("Output_Images/drawnimage.jpg")
    
    #Open the output drawn image
    opendraw = Image.open("Output_Images/drawnimage.jpg")
    opendraw.show()
    

    Output

    drawnimage

    Example - Adding Blue Text to an Image

    Here this is another example using the Draw() method for adding text at the middle of the image.

    main.py

    from PIL import Image, ImageDraw, ImageFont
    
    #Open an image
    image = Image.open("Images/faces.jpg")
    
    #Create a drawing object
    draw = ImageDraw.Draw(image)
    
    #Define text attributes
    text = "Welcome to Tutorialspoint"
    font = ImageFont.truetype("arial.ttf", size=30)
    text_color = (255, 0, 0)
    
    #Add text to the image
    draw.text(xy=(50, 50), 
       text = text,
       font = font,
       fill= text_color)
    
    #Save or display the image with the added drawing elements
    image.save("Output_Images/drawnimage.jpg")
    
    #Open the output drawn image
    opendraw = Image.open("Output_Images/drawnimage.jpg")
    opendraw.show()
    

    Output

    drawnimage faces

    Drawing Rectangle on the Image

    In the Pillow library (PIL) the PIL.ImageDraw.Draw.rectangle() method is used to draw a rectangle on an image using a specified outline and fill color. This method is part of the ImageDraw module and is typically called on an ImageDraw object created using PIL.ImageDraw.Draw().

    Syntax

    The following is the syntax and parameters of the PIL.ImageDraw.Draw.rectangle() method −

    ImageDraw.Draw.rectangle(xy, outline=None, fill=None, width=0)
    

    Where,

    • xy − This parameter specifies the coordinates of the rectangle as a tuple of two points. Each point is represented as (x1, y1) and (x2, y2) in which (x1, y1) is the upper-left corner and (x2, y2) is the lower-right corner of the rectangle.

    • outline − This parameter is optional and specifies the color of the outline of the rectangle. We can provide a color as a string e.g., "red" or "#FF0000" or as a tuple representing an RGB color (e.g., (255, 0, 0)). If set to None no outline will be drawn.

    • fill − This parameter is optional and specifies the color to fill the rectangle. Like the outline parameter we can specify the fill color as a string or an RGB tuple. If set to None the rectangle will not be filled.

    • width − This is an optional parameter to specify the width of the outline of the rectangle. By default it is 0 which means the rectangle will be filled without an outline.

    Input image to be used for the below two examples.

    black_white

    Example - Drawing a Rectangle over an Image

    In this example we are drawing a rectangle on the given input image by using the PIL.ImageDraw.Draw.rectangle() method.

    main.py

    from PIL import Image, ImageDraw
    
    #Open an image
    image = Image.open("Images/black_white.jpg")
    
    #Create a drawing object
    draw = ImageDraw.Draw(image)
    
    #Define the coordinates for the rectangle
    xy = [(100, 100), (200, 200)]
    
    #Draw a filled red rectangle
    draw.rectangle(xy, outline="blue", fill="red", width = 3)
    
    #Save or display the modified image
    image.save("Output_Images/output.jpg")
    image.show()
    

    Output

    rect_output

    Example - Drawing an Empty Rectangle Over an Image

    Here this is another example of drawing the rectangle with the specifying the outline as Blue and fill parameter as None.

    from PIL import Image, ImageDraw
    
    #Open an image
    image = Image.open("Images/black_white.jpg")
    
    #Create a drawing object
    draw = ImageDraw.Draw(image)
    
    #Define the coordinates for the rectangle
    xy = [(100, 100), (200, 200)]
    
    #Draw a filled red rectangle
    draw.rectangle(xy, outline= "Blue", fill= None, width = 2)
    
    #Save or display the modified image
    image.save("Output_Images/output.jpg")
    image.show()
    

    Output

    rect_imagedraw

    Drawing Line on the Image

    PIL.ImageDraw.Draw.line() is a method provided by the Python Imaging Library (PIL) or the Pillow library. Pillow is a more modern and actively maintained fork of PIL that is used to draw a line on an image. This method is part of the ImageDraw module within PIL/Pillow which is used for drawing shapes, text, and other graphics on images.

    Syntax

    Here the below is the syntax of the PIL.ImageDraw.Draw.line() method −

    PIL.ImageDraw.Draw.line(xy, fill=None, width=0, joint=None)
    

    Where,

    • xy − A sequence of (x, y) coordinates specifying the endpoints of the line.

    • fill − This parameter is optional and specifies the color of the line. It can be a string specifying a color name a (R, G, B) tuple or an integer value. If not specified, the line will be black.

    • width − This parameter is optional and specifies the line's width in pixels. The default value is 0 which means the line will be 1 pixel wide.

    • joint − This parameter is optional and can be used to specify the joint style for the line. It can be one of the following values −

      • None (default) − The line has regular joints.

      • curve − The line has rounded joints.

      • miter − The line has pointed joints.

    Input image to be used for the below two examples.

    faces

    Example - Drawing a Line over an Image

    In this example we are drawing a line on the input image by using PIL.ImageDraw.Draw.line() method.

    main.py

    from PIL import Image, ImageDraw, ImageFont
    
    #Open an image
    image = Image.open("Images/faces.jpg")
    
    #Create a drawing object
    draw = ImageDraw.Draw(image)
    
    #Draw a line
    line_coordinates = [(100, 200), (200, 200)]
    draw.line(line_coordinates,width=10)
    
    #Save or display the image with the added drawing elements
    image.save("Output_Images/drawnimage.jpg")
    
    #Open the output drawn image
    opendraw = Image.open("Output_Images/drawnimage.jpg")
    opendraw.show()
    

    Output

    lineimage

    Example - Adding Curved Line to an Image

    This is another example of the PIL.ImageDraw.Draw.line() method by specifying the joint parameter as curve.

    main.py

    from PIL import Image, ImageDraw
    
    #Open an image
    image = Image.open("Images/faces.jpg")
    
    #Create a drawing object
    draw = ImageDraw.Draw(image)
    
    #Define the endpoints and draw a red line
    line_color = "Yellow"  
    #Red color
    start_point = (0, 10)
    end_point = (200, 500)
    line_width = 3
    draw.line([start_point, end_point], fill=line_color, width=line_width, joint = "curve")
    
    #Save or display the modified image
    image.save("output.jpg")
    image.show()
    

    Output

    lineimage draw

    Drawing Polygon on the Image

    PIL.ImageDraw.Draw.polygon() is a method provided by the ImageDraw object in the Pillow library. It allows us to draw a polygon on an image. A polygon is a closed shape with multiple sides so we can specify the coordinates of the vertices to define the shape of the polygon.

    This method is part of the ImageDraw.Draw object and is used to create and fill a polygon shape with a specified color.

    Syntax

    The following is the syntax of the PIL.ImageDraw.Draw.polygon() method −

    PIL.ImageDraw.Draw.polygon(xy, fill=None, outline=None)
    

    Where,

    • xy − This is a list of tuples or a flat list of coordinates specifying the vertices of the polygon. Each tuple or pair of coordinates represents a vertex of the polygon.

    • fill − This parameter is optional and specifies the fill color for the interior of the polygon. If we want the polygon to have no fill and we can set this to None.

    • outline − This parameter is optional and specifies the color of the outline or border of the polygon. If we don't want an outline then we can set this to None.

    Input image to be used for the below two examples.

    black_white

    Example - Drawing a Polygon over Image

    In this example we are drawing a polygon on the image by using the PIL.ImageDraw.Draw.polygon() method and specifying the parameters xy, fill and outline.

    main.py

    from PIL import Image, ImageDraw
    
    #Open an image
    image = Image.open("Images/black_white.jpg")
    
    #Create a drawing object
    draw = ImageDraw.Draw(image)
    
    #Define the vertices of the polygon
    polygon_vertices = [(100, 100), (200, 100), (150, 200)]
    
    #Draw a filled polygon with a blue interior and a red outline
    draw.polygon(polygon_vertices, fill="blue", outline="red")
    
    #Save or display the modified image
    image.save("Output_Images/output.jpg")
    image.show() 
    

    Output

    polygon

    Example - Drawing Overlay Polygon on an Image

    Here this is another example in which we are passing the fill parameter of PIL.ImageDraw.Draw.polygon() method as None to avoid filling the polygon.

    main.py

    from PIL import Image, ImageDraw
    
    #Open an image
    image = Image.open("Images/bw.png")
    
    #Create a drawing object
    draw = ImageDraw.Draw(image)
    
    #Define the vertices of the polygon
    polygon_vertices = [(100, 100), (200, 100), (150, 200),(100,150),(90,100)]
    
    #Draw a filled polygon with a blue interior and a red outline
    draw.polygon(polygon_vertices, fill= None, outline="red")
    
    #Save or display the modified image
    image.save("Output_Images/output.jpg")
    image.show()
    

    Output

    imagedraw polygon

    ImageDraw Module Methods

    In addition to the above methods, This module offers many other specific methods that can be used for specific conditions. Let's explore and understand the basic fuctionality of each method −

    Sr.No. Methods with Description
    1

    ImageDraw.arc()

    Draws an arc inside a specified bounding box.

    2

    ImageDraw.chord()

    Draws a chord (a segment of a circle) inside a bounding box.

    3

    ImageDraw.pieslice()

    Draws a filled pie slice inside a bounding box.

    4

    ImageDraw.point()

    Draws points (single pixels) at specified coordinates on an image.

    5

    ImageDraw.regular_polygon()

    Draws a regular polygon with a given bounding circle.

    6

    ImageDraw.rounded_rectangle()

    Draws a rounded rectangle.

    7

    ImageDraw.multiline_text()

    Draws multiline text at a specified position on an image.

    Python Pillow - Concatenating Images



    Concatenating two images with Pillow typically refers to combining or joining two separate images to create a single image either horizontally or vertically. This process allows us to merge the content of the two images into a larger image.

    Pillow is a Python Imaging Library (PIL) which provides various methods and functions to perform image manipulation including image concatenation. When concatenating images we can choose to stack them on top of each other vertical concatenation or place them side by side horizontal concatenation.

    There are no direct methods in pillow to concatenate the images but we can perform that by using the paste() method in python.

    Here is a step-by-step guide on how to perform concatenation of two Images.

    • Import the necessary modules.

    • Load the two images that we want to concatenate.

    • Decide whether we want to concatenate the images horizontally or vertically.

    • Save the concatenated image to a file.

    • Optionally we can display the concatenated image. This step is useful for visualizing the result but it's not required.

    Following is the input images used in all the examples of this chapter.

    butterfly original image flowers

    Example - Concatenating Images Horizontally

    In this example we are concatenating two input images horizontally.

    main.py

    from PIL import Image
    image1 = Image.open("Images/butterfly.jpg")
    image2 = Image.open("Images/flowers.jpg")
    result = Image.new("RGB", (image1.width + image2.width, image1.height))
    result.paste(image1, (0, 0))
    result.paste(image2, (image1.width, 0))
    result.save("Output_Images/horizontal_concatenated_image.png")
    result.show()
    

    Output

    horizontal concatenated

    Example - Concatenating Images Vertically

    Here in this example we are concatenating the given two input images vertically.

    main.py

    from PIL import Image
    image1 = Image.open("Images/butterfly.jpg")
    image2 = Image.open("Images/flowers.jpg")
    result = Image.new("RGB", (image1.width, image1.height + image2.height))
    result.paste(image1, (0, 0))
    result.paste(image2, (0, image1.height))
    result.save("Output_Images/vertical_concatenated_image.png")
    result.show()
    

    Output

    vertical concatenated

    Python Pillow - Creating Thumbnail of an Image



    Thumbnails are typically used for displaying image previews or smaller representations of the original image. They are useful for optimizing web pages and improving the loading speed of image-heavy applications. Pillow provides a convenient way to generate thumbnails from images. Here are some key points about thumbnails in Pillow.

    • Preservation of Aspect Ratio − When creating a thumbnail Pillow maintains the aspect ratio of the original image. This means that the width and height of the thumbnail are adjusted in proportion to the original image so the image does not appear distorted.

    • Reduced File Size − Thumbnails are smaller in size compared to the original image. This reduction in size is useful for optimizing web pages or displaying images in constrained spaces such as in galleries or lists.

    • Convenience − It simplifies the process of creating thumbnails. It resizes the image while preserving the aspect ratio and it provides an easy way to save the resized image to a file.

    • Quality Control − We can control the quality of the thumbnail using various parameters such as the size, filter type for resizing and compression settings if we are saving the thumbnail in a compressed format like JPEG.

    In pillow we have the method namely thumbnail() which allows us to specify the dimensions and shape for the thumbnail image. We can create the thumbnails in two different shapes one is square and the other is circle.

    Creating square Thumbnails

    In this chapter we are going to see how to create a square thumbnail by using the thumbnail() method of the pillow library.

    The syntax and parameters for thumbnail() method is as follows.

    image.thumbnail(size, resample=Image.BOX)
    

    Where,

    • size (required) − This parameter specifies the dimensions i.e. width and height for the thumbnail as a tuple (width, height). We can also specify just one dimension and the other dimension will be automatically calculated to maintain the aspect ratio.

    • resample (optional) − This parameter defines the resampling filter to use when resizing the image. It can be one of the following constants −

      • Image.NEAREST (default) − Nearest-neighbor sampling.

      • Image.BOX − Box sampling, which is similar to the nearest-neighbor but generally gives slightly smoother results.

      • Image.BILINEAR − Bilinear interpolation.

      • Image.HAMMING − Hamming-windowed sinc interpolation.

      • Image.BICUBIC − Bicubic interpolation.

      • Image.LANCZOS − Lanczos-windowed sinc interpolation.

    Example - Creating a Square Thumbnail

    In this example we are creating the square thumbnail by using the thumbnail() method by specifying the width and height parameters of the thumbnail to the resize parameter.

    main.py

    from PIL import Image
    
    #Open the image
    image = Image.open("Images/tutorialspoint.jpg")
    
    #Define the thumbnail size as a tuple (width, height)
    thumbnail_size = (200, 200)
    
    #Create a thumbnail
    image.thumbnail(thumbnail_size, resample = Image.BOX )
    image.save("Output_Images/square_thumbnail_image.jpg")
    image.show() 
    

    Output

    tutorialspoint

    Example - Creating a Smaller Thumbnail

    Here is another example of creating a square thumbnail with width 100 and height as 100 by using the thumbnail() module.

    main.py

    from PIL import Image
    
    #Open the image
    image = Image.open("Images/butterfly.jpg")
    
    #Define the thumbnail size as a tuple (width, height)
    thumbnail_size = (100, 100)
    
    #Create a thumbnail
    image.thumbnail(thumbnail_size, resample = Image.Resampling.BILINEAR)
    image.save("Output_Images/square_thumbnail_image.png")
    image.show() 
    

    Output

    square thumbnail image

    Creating circle Thumbnails

    In the above section, we have gone through what is thumbnail and how to create the square thumbnail using the pillow thumbnail() method. Now, we are going to see the circle thumbnail creation. Circle thumbnails means the thumbnail will be in the circle shape.

    The syntax and parameters of the thumbnail() method for creating the circle thumbnail are same as the square thumbnail.

    Here are the steps to be followed to create the circular thumbnail.

    • Import the necessary modules Image and ImageDraw from the Pillow library.

    • Use the Image.open() method to load the original image.

    • Determine the dimensions of the original image using the size attribute.

    • Create a new object from the mask image using the ImageDraw.Draw() method.

    • Draw an ellipse on the mask image using the draw.ellipse() method. Centering the image to the center of the ellipse.

    • Create a new image with the same dimensions as the original image with a transparent background using the Image.new() method.

    • Use the save() method to save the circle thumbnail image.

    • Use the show() method to display the created circle thumbnail image.

    Example - Creating Circular Thumbnail

    In this example we are creating the circular thumbnail by using the thumbnail() method of the pillow library.

    main.py

    #importing the required libraries
    from PIL import Image, ImageDraw 
    
    #open image file
    img = Image.open('Images/butterfly.jpg')
    
    #resize image
    img.thumbnail((2000, 2000))
    
    #create circular mask
    mask = Image.new('L', img.size, 0)
    draw = ImageDraw.Draw(mask)
    center = [50, 50]
    radius = 10
    draw.ellipse((center[0] - radius, center[1] - radius, center[0] + radius, center[1] + radius), fill = 255)
    
    #apply mask to image
    result = Image.new('RGBA', img.size, (255, 255, 255, 0))
    result.paste(img, (0, 0), mask)
    
    #save circular thumbnail image
    result.save('Output_Images/circular_thumbnail1.png')
    
    #showing the image using show() function
    result.show()
    

    Image to be used

    butterfly original image

    Output

    circular thumbnail

    Python Pillow - Creating Watermark over Image



    What is Watermark?

    A watermark is a recognizable and often transparent image or text that is superimposed onto another image, document or object to indicate ownership, authorship or origin. Watermarks are typically used to protect intellectual property and content which prevent unauthorized use or distribution and provide attribution. They serve various purposes as mentioned below −

    • Copyright Protection − Artists, photographers and content creators often use watermarks to protect their intellectual property by marking their work with their name, logo or copyright information. This helps deter unauthorized use or distribution of their content.

    • Branding − Companies and organizations use watermarks to brand their images or documents with their logos, names or slogans. This reinforces their brand identity and makes it clear where the content originated.

    • Document Verification − Watermarks can be used on official documents such as certificates to prevent forgery or unauthorized reproduction. For example diplomas or notarized documents may have watermarks.

    • Security − In currency and other security documents intricate and often invisible watermarks are used to deter counterfeiting. These watermarks are difficult to reproduce accurately making it easier to detect counterfeit bills or documents.

    • Image Attribution − In the context of stock photography and image licensing watermarks can be used to display a preview of the image with a watermark. When a user purchases the image they receive a version without the watermark.

    • Digital Media − In the digital world watermarks are often used on images and videos shared online to protect content. They can also be used to give credit to the original creator.

    Watermarks can take various forms such as text, logos, patterns or even invisible data embedded within the content. They are typically placed in a manner that is difficult to remove without compromising the quality of the content and their purpose is to provide a visual or digital indicator of authenticity or ownership.

    Creating the text watermark

    Now let's explore how to create a text watermark by using the pillow library. In pillow there is no direct method to create the watermarks but we can achieve it by using the ImageDraw, ImageFont and Image methods.

    Following is the input image used in all the examples of this chapter.

    butterfly

    Example - Adding Text as Watermark to an Image

    In this example we are creating the text Tutorialspoint as the watermark by using the pillow library.

    main.py

    from PIL import Image, ImageDraw, ImageFont
    original_image = Image.open("Images/butterfly.jpg")
    draw = ImageDraw.Draw(original_image)
    watermark_text = "Tutorialspoint"
    font_size = 20
    font = ImageFont.truetype("arial.ttf", font_size)  
    text_color = (255, 255, 255)  
    
    #White color (RGB)
    bbox = draw.textbbox((0,0),watermark_text, font)
    # bbox format - (left, top, right, bottom)
    text_width = bbox[2] - bbox[0]
    text_height = bbox[3] - bbox[1]
    image_width, image_height = original_image.size
    margin = 10  
    
    #Margin from the right and bottom edges
    position = (image_width - text_width - margin, image_height - text_height - margin)
    draw.text(position, watermark_text, font=font, fill=text_color)
    original_image.save("Output_Images/watermarked_image.png")
    original_image.show() 
    

    Output

    watermarked

    Creating the image Watermark

    Previously we created the text watermark on an image, in the same way we can create an image as the watermark by using the ImageDraw, copy and paste methods available in pillow.

    Example - Creating Image as watermark

    In this example we are creating the Tutoriaslpoint logo image as the watermark by the methods available in pillow.

    main.py

    from PIL import Image
    original_image = Image.open("Images/butterfly.jpg")
    watermark = Image.open("Images/tutorialspoint.jpg")  
    #Use the appropriate image file for your watermark
    
    #Resize the watermark image to a specific width or height
    target_width = 200  
    
    #Adjust this to our preferred size
    aspect_ratio = float(target_width) / watermark.width
    target_height = int(watermark.height * aspect_ratio)
    watermark = watermark.resize((target_width, target_height),Image.Resampling.LANCZOS)
    watermarked_image = original_image.copy()
    
    #Adjust the position where you want to place the watermark (e.g., bottom right corner)
    position = (original_image.width - watermark.width, original_image.height - watermark.height)
    watermarked_image.paste(watermark, position)
    watermarked_image.save("Output_Images/watermarked_image.jpg")
    watermarked_image.show()
    

    Output

    watermarked Tutorialspoint

    Python Pillow - Image Sequences



    Introduction to Image Sequences

    Image sequences in Pillow (Python Imaging Library) refer to a collection of individual images displayed in a specific order to create an animation. The popular file formats of the image sequences are GIFs, APNG (Animated Portable Network Graphics), FLI/FLC, TIFF files(with more than one frame), and more.

    The Python Pillow library provides the ImageSequence module to work with image sequences and animated pictures. The main feature of this ImageSequence module is, its ability to iterate over the frames of an image sequence. We can do this by using the ImageSequence.Iterator class which acts as a wrapper for image sequences and simplifies the process of accessing individual frames.

    Reading Image Sequences

    Reading image sequences is a fundamental operation when working with animations or multi-frame images. You can open and read an image sequences using the Image.open() method in the Python Pillow (PIL) library.

    Example - Reading Image Sequences

    Here's an example demonstrating how to read image sequences using the Python Pillow Image.open() method.

    main.py

    from PIL import Image, ImageSequence
    
    # Open the image sequence file
    image = Image.open("Images/Book_animation.gif")
    
    # Display the opened image
    image.show()
    

    Output

    While executing the above code we get the following output −

    imageseuence allframes

    When an image sequence file is opened, PIL automatically loads the first frame. To access other frames in the sequence, we need to iterate through them using the ImageSequence.Iterator class, which provides a convenient way to loop through all the frames in the image sequence.

    Accessing Frames in an Image Sequence

    The ImageSequence.Iterator() class in Python Pillow allows us iterate over the frames of an image sequence. It accepts an image object as a parameter and implements an iterator object that can be used by a user to iterate over an image sequence. We can use the operator to access individual frames in the sequence or we can use the for loop to iterate over all of the frames.

    The syntax for using the ImageSequence.Iterator() class is as follows −

    image_object = PIL.ImageSequence.Iterator(image)
    

    where image_object is the iterator used to loop over the frames of the image sequence, and image is our input image object (an instance of PIL.Image.)

    To work with ImageSequence.Iterator in Pillow, follow these steps

    • Import necessary modules such as Image and ImageSequence.

    • Load the first image in the sequence using the Image.open() method.

    • Iterate through the frames using PIL.ImageSequence.Iterator() class.

    • Within the loop, process or manipulate each frame as needed, which can include any of the following operations such as resizing, adding text, applying filters, or other image manipulation techniques available in Pillow.

    • Save the processed frames as separate images, using the save() method.

    Example - Iterating Image frames

    Below is an example that demonstrates using ImageSequence.Iterator() class to iterate over the frames of an image sequence.

    main.py

    from PIL import Image, ImageSequence
    
    # Open an image sequence file
    image = Image.open("Images/Book_animation.gif")
    
    index = 0
    
    # Iterate through the frames
    for frame in ImageSequence.Iterator(image):
        # Process or manipulate the current frame here
        frame.convert('RGB').save("Output_Images/frame % d.jpg" % index)
        index += 1
    
    print("All frames of the ImageSequence are saved separately.")
    

    Output

    All frames of the ImageSequence are saved separately.
    

    When you execute the above code, all frames of the image sequence are saved separately in your working directory.

    imageseuence ex2

    We can also access various properties of individual frames within an image sequence. For example we can retrieve the duration of each frame which determines how long it is displayed in an animation.

    Example - Creating Image Sequences

    While the primary use of the Image Sequence module is to extract frames from existing sequences we can also create our own image sequences. Learn more about Creating Animated GIFs here.

    Here is a basic example that demonstrating how to create a GIF image sequence from a list of image.

    main.py

    from PIL import Image
    
    # Create a list of image objects
    images = [Image.open(f"Images/split{i}.jpg") for i in range(1,4)]
    
    # Save the image sequence as a GIF
    images[0].save(
        "Output_Images/creating_animation.gif",
        save_all=True,
        append_images=images[1:],
        duration=200,
        loop=0
    )
    
    print("Image sequence created and saved as creating_animation.gif")
    

    Output

    Image sequence created and saved as creating_animation.gif
    
    image_sequences_ex3 gif

    Modifying and Saving Image Sequences

    Image sequences can be manipulated and saved just like regular images. For modifying the image sequences you can use the all_frames() method from the Pillow's ImageSequence module. This method applies a specified function to all frames in the image sequence and returns a list containg the all separated frames. By using this method, we can iterate over each frame in an image sequence and apply the necessary transformations.

    Following is the syntax of the ImageSequence.all_frames() method −

    PIL.ImageSequence.all_frames(im,func)
    

    Where,

    • im − An image sequence.

    • func − A function to apply to all of the image frames.

    After making changes to an image sequence we can save it as a new image sequence or a different format depending on our needs.

    Example - Modifying Sequences

    This example demonstrates how to add text to each frame of an image sequence and save the modified sequence.

    main.py

    from PIL import Image, ImageSequence, ImageDraw
    
    # Open the image sequence
    im = Image.open('Images/book_animation.gif')
    
    # Define a function to add text to each frame
    def add_text(im_frame):
        draw = ImageDraw.Draw(im_frame)
        draw.text((150, 100), "Tutorialspoint", fill='green')
        return im_frame
    
    # Apply the add_text function to all frames in the image sequence
    ims = ImageSequence.all_frames(im, add_text)
    
    # Save the modified frames as a new GIF
    ims[0].convert('RGB').save('Output_Images/modified_image_sequences.gif', save_all=True, append_images=ims[1:])
    print('Text added to each frame of the given ImageSequence.')

    Output

    Text added to each frame of the given ImageSequence.
    
    modified_image_sequences

    Conclusion

    Pillow's Image Sequence module is a powerful tool for working with image sequences and creating animations. We can easily iterate over frames, extract properties and apply various image operations to create dynamic visuals. Whether we are working with GIFs or creating custom animations or processing image sequences Pillow provides the necessary functions and classes to simplify the process.

    Python Pillow - Colors on an Image



    In Pillow (Python Imaging Library) colors on an image are defined as a combination of red (R), green (G) and blue (B) components which are commonly known as the RGB color model. This model represents colors as a mixture of these three primary colors with each component ranging from 0, i.e. minimum intensity to 255, i.e. maximum intensity. A fourth component, alpha (A) is often included for transparency with 0 representing full transparency and 255 representing full opacity.

    Defining colors accurately is crucial when working with images as it determines the appearance and composition of the image. Pillow provides various ways to represent and define colors making it flexible for various image processing and manipulation tasks.

    Here is a detailed explanation of these color components −

    Red (R)

    • The red component represents the amount of red in a color.

    • When R is 0 which represents there is no red and resulting in a shade of cyan or green.

    • When R is 255 which specifies there is maximum red intensity and produces a pure red color.

    • Intermediate values produce varying shades of red from pink to orange.

    Green (G)

    • The green component represents the amount of green in a color.

    • When G is 0 which represents there is no green and results in shades of magenta or blue.

    • When G is 255 which represents there is maximum green intensity and results in a pure green color.

    • Intermediate values produce different shades of green from lime to teal.

    Blue (B)

    • The blue component represents the amount of blue in a color.

    • When B is 0 which represents there is no blue and results in shades of yellow or red.

    • When B is 255 which represents there is maximum blue intensity by producing a pure blue color.

    • Intermediate values create various shades of blue from navy to sky blue.

    Alpha (A)

    • The alpha component is optional but essential for controlling transparency.

    • When A is 0 which represents the pixel is fully transparent allowing what's behind it to show through.

    • When A is 255 which represents the pixel is fully opaque and it completely covers what's underneath.

    • Intermediate alpha values create varying levels of transparency allowing a pixel to be partially see-through.

    To represent a color in Pillow we typically use a tuple or list with four values in the order (R, G, B, A) to specify the color of a pixel. For example (255, 0, 0, 255) represents a fully opaque red pixel while (0, 255, 0, 128) represents a semi-transparent green pixel.

    Example - Creating a image

    Let's see an example of creating an image using the Python Pillow with RGBA color representation.

    main.py

    from PIL import Image
    
    # Create an RGBA image with Semi-transparent green
    image = Image.new('RGBA', (700, 300), (0, 255, 0, 128))  
    
    # Display the resultant Semi-transparent green image
    image.show()
    

    Output

    On executing the above program you will get output RGBA like below −

    colors_on_an_image_ex1

    Understanding the RGB color model and the alpha component is fundamental when working with image processing and manipulation in Pillow as it allows us to create, modify and combine colors and images in various ways.

    Example - Hexadecimal Color Representation

    Hexadecimal color codes are widely used on the web and in graphics design. In Pillow we can define a color using a hexadecimal string which represents the RGB values. The format is #RRGGBB where RR, GG and BB are two-digit hexadecimal values for red, green and blue respectively.

    Here is an example of creating an image using the Python Pillow Hexadecimal color representation. In this example we are creating red colored image with 80% opacity.

    main.py

    from PIL import Image
    
    # Create a red colored image with 80% opacity
    image = Image.new('RGBA', (700, 300), "#ff0000cc")  
    
    # Display the resultant image
    image.show()
    

    Output

    when you run the above program you will get following output −

    colors_on_an_image_ex2

    Example - Named Colors

    Pillow ImageColor module provides a set of named colors (commonly used HTML color names), allowing us to use these color names instead of numerical values. For example, the name red indicates pure red color, and it is important to note that color names are case insensitive, meaning "red" and "Red" are treated the same.

    The following example demonstrates how to access and print the named colors available in Pillow's ImageColor module.

    main.py

    from PIL import ImageColor
    
    # Access all the named colors
    color_map = ImageColor.colormap
    
    # Count the number of named colors
    num_colors = len(color_map)
    
    # Print the available named colors and count
    print(color_map)
    print(f'Total number of named colors: {num_colors}')
    

    Output

    when you run the above program you will get similar output like below −

    {'aliceblue': '#f0f8ff', 'antiquewhite': '#faebd7', 'aqua': '#00ffff', ...}
    Total number of named colors: 148
    

    Example - Grayscale Colors

    Grayscale colors are represented by a single intensity value ranging from 0 (black) to 255 (white). We can define grayscale colors using a single integer value.

    Here is an example of creating a new grayscale image with grayscale color representation.

    main.py

    from PIL import Image, ImageDraw, ImageFont
    
    # Create a greyscale image with color intensity value
    image = Image.new('L', (700, 300), 100)  
    
    #Create a drawing object
    draw = ImageDraw.Draw(image)
    
    #Define text attributes
    text = "Welcome to Tutorialspoint..."
    font = ImageFont.truetype("arial.ttf", size=35)
    text_position = (150, 130)
    
    # Specify the text color using the single integer value
    text_color = 255  
    
    #Add text to the image
    draw.text(text_position, text, fill=text_color, font=font)
    image.show()
    

    Output

    Following is the output of the above program −

    colors_on_an_image_ex3

    Python Pillow - Colors on an Image



    What is creating Images with colors?

    Creating images with color in Pillow (Python Imaging Library, now known as Pillow) involves creating new images filled with specific colors. Creating images with color in Pillow involves generating an image of a specific size and filling it with a desired color. This process allows us to generate solid-colored images which can be useful for various purposes such as creating backgrounds, placeholders or simple graphics.

    In pillow we have the method namely new() which is used to create the images with colors. At the beginning we have seen the syntax and parameters of the new() method available in the Image module.

    There are few steps to be followed to create the image with the defined color. Let's see them one by one.

    • Import the necessary modules

      To use Pillow we need to import the required modules typically Image and ImageDraw. The Image module provides functions for creating and manipulating images and ImageDraw is useful for drawing shapes and text on the images.

    • Define the image size and color

      Determine the dimensions i.e. width and height of the image we want to create and specify the color we want to use. Colors can be defined in various ways such as RGB tuples or color names.

    • Create a new image with the specified size and color

      Use the Image.new() method to create a new image. We can specify the image mode which can be "RGB," "RGBA," "L" (grayscale) and others depending on our needs. We can also provide the size and color for the image.

    • Optionally draw on the image

      If we want to add shapes, text or other elements to the image then we can use the ImageDraw module. This allows us to draw on the image using various methods like draw.text(), draw.rectangle() and so on.

    • Save or display the image

      We can save the created image to a file in a specific format (e.g., PNG, JPEG) using the save() method. Alternatively we can display the image using the show() method which opens the image in the default image viewer.

    Example - Creating a Solid Red Image

    Here in this example we are creating the solid red color image by using the new() method of the Image module.

    main.py

    from PIL import Image, ImageDraw
    
    #Define image size (width and height)
    width, height = 400, 300
    
    #Define the color in RGB format (e.g., red)
    color = (255, 0, 0)  
    
    #Red
    #Create a new image with the specified size and color
    image = Image.new("RGB", (width, height), color)
    
    #Save the image to a file
    image.save("Output_Images/colored_image.png")
    
    #Show the image (opens the default image viewer)
    image.show()
    

    Output

    colored imagedraw

    Example - Adding Text to Image

    In this example we are using the optional feature i.e adding the text by using the ImageDraw module Draw() method.

    main.py

    from PIL import Image, ImageDraw
    
    #Define image size (width and height)
    width, height = 400, 300
    
    #Define the color in RGB format (e.g., red)
    color = (255, 0, 0)  
    
    #Red
    #Create a new image with the specified size and color
    image = Image.new("RGB", (width, height), color)
    
    #Optional: If you want to draw on the image, use ImageDraw
    draw = ImageDraw.Draw(image)
    draw.text((10, 10), "Hello, Welcome to Tutorialspoint", fill=(255, 255, 255))  
    
    #Draw white text at position (10, 10)
    #Save the image to a file
    image.save("Output_Images/colored_image.png")
    
    #Show the image (opens the default image viewer)
    image.show()
    

    Output

    colored imagedraw tp

    Python Pillow - Converting Color String to RGB Color Values



    Converting a color string to RGB color values is the process of taking a textual representation of a color and converting it into the numerical values that represent the color in the Red, Green and Blue (RGB) color model. In the RGB color model colors are specified by three numbers each ranging from 0 to 255 in which,

    • The first number represents the amount of red in the color.

    • The second number represents the amount of green in the color.

    • The third number represents the amount of blue in the color.

    For example, the color red is typically represented as (255, 0, 0) in RGB values which means it has maximum red (255) and no green (0) or no blue (0).

    Converting color string to RGB Color values

    To perform the conversion of color string into RGB values we can use the getrgb() function in the ImageColor module of the Python Pillow library.

    Syntax

    The below is the syntax and parameters of the ImageColor.getrgb() method −

    ImageColor.getrgb(color)
    

    Where,

    • color − This is a string representing the color we want to convert to RGB values. It can be a color name (e.g., "red", "blue") or a hexadecimal color code (e.g., "#00FF00") or other color representations that Pillow supports.

    Example - Converting Blue Color to RGB Tuple

    In this example the ImageColor.getrgb() function takes a color string blue as an argument and returns a tuple of RGB values.

    main.py

    from PIL import ImageColor
    
    #Define a color string
    color_string = "blue"
    
    #Convert the color string to RGB values
    rgb_color = ImageColor.getrgb(color_string)
    
    #Print the RGB values
    print("The conversion of the color string",color_string,":",rgb_color)
    

    Output

    The conversion of the color string blue: (0, 0, 255)
    

    Example - Converting Yellow Color to RGB Tuple

    Here, in this example we are converting the yellow color string into the RGB values. We are passing the color string argument as a hexadecimal value to the ImageColor.getrgb() method.

    main.py

    from PIL import ImageColor
    
    #Define a color string
    color_string = "#FFFF00"
    
    #Convert the color string to RGB values
    rgb_color = ImageColor.getrgb(color_string)
    
    #Print the RGB values
    print("The conversion of the color string",color_string,":",rgb_color)
    

    Output

    The conversion of the color string "#FFFF00": (255, 255, 0)
    

    Python Pillow - Converting Color String to Grayscale Color Values



    The ImageColor.getcolor() function in the Python Pillow (PIL) library is same as the ImageColor.getrgb() which allows us to retrieve the color value of a given color name or hexadecimal code.

    Syntax

    The following is the syntax and parameters as follows −

    ImageColor.getcolor(color, mode)
    
    • color − This is a string representing the color you want to retrieve the value for. It can be a color name (e.g., "red", "blue") or a hexadecimal color code (e.g., "#00FF00") or other color representations that Pillow supports.

    • mode − This parameter specifies the color mode in which we want to retrieve the color value. The default value is "RGB" which means the color value will be returned as an RGB tuple. We can also specify other modes like "RGBA," "CMYK," "HSV" etc., depending on our needs.

    Example - Converting Blue Color to Grayscale

    In this example we use ImageColor.getcolor() to retrieve the RGB value of the color blue and the RGBA value of the color green in RGBA mode. We can adjust the color and mode parameters to suit our specific requirements.

    main.py

    from PIL import ImageColor
    
    #Get the RGB value of the color "blue"
    blue_rgb = ImageColor.getcolor("blue", mode = "RGB")
    
    #Get the RGBA value of the color "green" in RGBA mode
    green_rgba = ImageColor.getcolor("green", mode="RGBA")
    print("Blue (RGB):", blue_rgb)
    print("Green (RGBA):", green_rgba)
    

    Output

    Blue (RGB): (0, 0, 255)
    Green (RGBA): (0, 128, 0, 255)
    

    Example - Converting Hexadecimal Color Value to Grayscale

    Here, in this example we are giving the hexadecimal value as the color string argument to the ImageColor.getcolor() method.

    main.py

    from PIL import ImageColor
    
    #Get the RGB value of the color "blue"
    blue_rgb = ImageColor.getcolor("#8A2BE2", mode = "RGB")
    
    #Get the RGBA value of the color "green" in RGBA mode
    green_rgba = ImageColor.getcolor("#008000", mode="RGB")
    print("Violet (RGB):", blue_rgb)
    print("Green (RGB):", green_rgba)
    

    Output

    Violet (RGB): (138, 43, 226)
    Green (RGB): (0, 128, 0)
    

    Python Pillow - Change the Color by Changing the Pixel Values



    Changing the color of an image by changing the pixel values in Pillow (PIL) involves manipulating the individual pixel values of an image to achieve the desired color transformation. We can perform various color operations by altering the RGB values of each pixel.

    Modifying Pixel Values using the getdata() Method

    We have the method namely, getdata() in pillow. It can used to retrieve the pixel data of an image. It returns a sequence of pixel values typically as a one-dimensional list or iterable where each pixel value represents the color of a pixel in the image. By using the getdata() method, you can access and modify the pixel values of an image.

    The below is the syntax and parameters of the Image.getdata() method −

    Image.getdata(band=None)
    

    Where,

    • band − This specifies that what the band has to return. The default value is to return all bands. For returning a single band pass in the index value. For example 0 to get the Rband from an RGBimage.

    The below are the steps to be followed for changing the color pixels of an image.

    • Open the image that we want to modify using Pillow's Image.open() method.

    • Access the image data as a pixel-by-pixel list using image.getdata().

    • Create a new list of pixel values by changing the color as we desire.

    • Create a new image with the modified pixel values using Image.new().

    • Save or display the modified image using save().

    Example - Getting Pixels of an Image

    In this example we are getting the list of pixel data of the given input image by using the Image.getdata() method.

    main.py

    from PIL import Image
    
    #Open the image you want to modify
    image = Image.open("Images/python_logo.jpg")
    
    #Access the pixel data of the image
    pixels = list(image.getdata())
    print(pixels)
    

    Input Image

    python logo

    Output

    [(255, 255, 255, 255), (255, 255, 255, 255), ...]
    

    Example - Modifying the pixel of Image

    Here in this example we are modifying the pixel of the given input image into red by using the Image.getdata() method.

    main.py

    from PIL import Image
    
    #Open the image you want to modify
    image = Image.open("Images/three.jpg")
    
    #Access the pixel data of the image
    pixels = list(image.getdata())
    
    #Define the new color you want (e.g., red)
    new_color = (255, 0, 0)  
    #Red
    
    #Create a new list of pixel values with the new color
    modified_pixels = [new_color if pixel != (255, 255, 255) else pixel for pixel in pixels]
    
    #Create a new image with the modified pixel values
    modified_image = Image.new("RGB", image.size)
    modified_image.putdata(modified_pixels)
    
    #Save the modified image to a file
    modified_image.save("Output_Images/modified_image.jpg")
    
    #Display the modified image
    modified_image.show()
    

    Input Image

    balck three

    Output

    modified image

    Python Pillow - Reducing Noise



    Reducing noise in Pillow refers to the process of applying various techniques and filters to an image to remove or decrease unwanted artifacts or irregularities that can degrade the image quality. Image noise is random variations in brightness or color in images typically caused by factors such as low light conditions, electronic interference or imperfections in the image sensor. Reducing noise is an important step in image processing to improve the overall quality of images.

    Pillow (PIL) provides several built-in filters and methods for reducing noise in images. Some common techniques and filters for noise reduction in Pillow include −

    • Gaussian Blur − Applying a Gaussian blur filter to the image can help smooth out reduce noise by averaging the pixel values in the vicinity of each pixel. This creates a smoother appearance and can reduce the impact of noise. The degree of blurring can be adjusted to control the level of noise reduction.
    • Median Filter − Median filtering replaces each pixel's value with the median value of the neighboring pixels. The median filter is effective for removing salt-and-pepper noise where isolated pixels have extreme values. It replaces each pixel's value with the median value of neighboring pixels.
    • Bilateral Filter − The bilateral filter smooths the image while preserving edges. It can be effective at reducing noise while maintaining image details.
    • Denoising Algorithms − Pillow supports various denoising algorithms such as the bilateral filter, Total Variation (TV) denoising algorithm or the Non-Local Means (NLMeans) filter which can be used to reduce noise while preserving image details.
    • Thresholding − We can apply a threshold to an image to remove noise by converting pixel values below a certain threshold to black and values above the threshold to white effectively binarizing the image.

    Python Pillow - Image.filter() Method

    Image.filter() is a method in the Python Imaging Library (PIL) or its fork. Pillow used to apply various image filters and enhancements to an image. Filters are image processing operations that can be used to modify an image in different ways such as blurring, sharpening or enhancing certain features. This method allows us to apply various predefined filters to an image.

    Pillow provides a variety of predefined filters that we can use with Image.filter(), including −

    • ImageFilter.BLUR − Applies a simple blur to the image.

    • ImageFilter.CONTOUR − Enhances the contours of objects in the image.

    • ImageFilter.DETAIL − Enhances the image's details.

    • ImageFilter.EDGE_ENHANCE − Emphasizes the edges in the image.

    • ImageFilter.EMBOSS − Adds a 3D embossing effect to the image.

    • ImageFilter.SHARPEN − Sharpens the image.

    Syntax

    The syntax and parameters for using Image.filter() is as follows −

    output_image = input_image.filter(filter_name, filter_parameters)
    

    Where,

    • input_image − This is the source image to which we want to apply the filter.

    • filter_name − This is a string specifying the name of the filter we want to apply. Pillow provides a variety of built-in filters and we can use one of these filter names as a string. For example "GaussianBlur," "MedianFilter," "Sharpen", etc. We can also define our custom filters by providing a kernel (a list of values) as a filter.

    • filter_parameters (optional) − Some filters may accept additional parameters that control the behavior of the filter. These parameters are specific to the particular filter being used. If the filter we are applying requires parameters we would pass them as arguments in the filter_parameters part.

    Example - Blurring an Image

    In this example we are trying to blur the image by passing the ImageFilter.BLUR as the input parameter to the Image.filter() method.

    main.py

    from PIL import Image, ImageFilter
    
    #Open an image
    input_image = Image.open("Images/flowers.jpg")
    
    #Apply Gaussian blur to the image
    output_image = input_image.filter(ImageFilter.BLUR())
    
    #Save the resulting image
    output_image.save("Output_Images/blur.jpg")
    output_image.show()
    

    Image to be used

    flowers

    Output

    blur flowers

    Example - Blurring a specific part of an Image

    Here in this example we are blurring a specified part of the image by using the ImageFilter.BoxBlur() method.

    main.py

    from PIL import Image, ImageFilter
    
    #Open an image
    input_image = Image.open("Images/rose.jpg")
    
    #Apply Gaussian blur to the image
    output_image = input_image.filter(ImageFilter.BoxBlur(20))
    
    #Save the resulting image
    output_image.save("Output_Images/blur.jpg")
    output_image.show()
    

    Image to be used

    flower

    Output

    blur rose

    Python Pillow - Changing Image Modes



    What is Changing Image Modes?

    In Pillow changing image modes refers to the process of converting an image from one color representation to another. Each mode represents a different way of encoding and interpreting color information in an image.

    Changing image modes is useful for various purposes such as preparing images for specific applications like printing, display or analysis. It allows us to adapt the color representation of an image to better suit our needs.

    In Pillow the Image class provides a method called convert() that allows us to change the mode of an image. The mode of an image determines the type and depth of pixel values it can contain.

    The following is the syntax and parameters of the convert() method of the Image class.

    original_image.convert(mode)
    

    Where,

    • original_image This is the source image whose mode we want to change.

    • mode This is a string specifying the desired mode for the new image.

    The below are the common changing Image modes.

    • L − 8-bit pixels represent black and white

    • RGB − 3x8-bit pixels represent true color

    • RGBA − 4x8-bit pixels represent true color with transparency

    • CMYK − 4x8-bit pixels represent color separation

    • HSV − Hue, saturation, value color space

    • 1 − 1-bit pixels, black and white which stored with one pixel per byte

    Following is the input image used in all the examples of this chapter.

    Rose

    Example - Changing Image to Black and White

    In this example we are changing the image mode into black and white by passing the mode argument as L to the convert() method.

    main.py

    from PIL import Image
    
    #Open an image
    original_image = Image.open("Images/rose.jpg")
    
    #Convert the image to grayscale (mode 'L')
    grayscale_image = original_image.convert("L")
    
    #Save the resulting image
    grayscale_image.save("Output_Images/output_grayscale.jpg")
    grayscale_image.show()
    

    Output

    output grayscale

    Example - Changing Image to 1 mode

    Here is the another example of changing the image mode to 1 by using the convert() method.

    main.py

    from PIL import Image
    
    #Open an image
    original_image = Image.open("Images/rose.jpg")
    
    #Convert the image to RGBA mode
    single_image = original_image.convert("1")
    
    #Save the resulting image
    single_image.save("Output_Images/output_single_image.jpg")
    single_image.show()
    

    Output

    output_single_image

    Python Pillow - Compositing Images



    What is compositing Image?

    Compositing images in Pillow involve combining two or more images to create a new image. This process often includes blending the pixel values of one image with another based on certain criteria such as transparency or specific blending modes.

    Pillow provides the Image.alpha_composite() method for compositing images especially when dealing with alpha (transparency) channels. It is commonly used for overlaying one image onto another adding watermarks or creating special effects.

    Here are the key concepts related to compositing images in Pillow −

    Image Composition

    • Combining images to create a new image by overlaying one image onto another.

    • The image composting is commonly used for adding watermarks or creating special effects.

    Alpha Channel

    • The alpha channel represents the transparency of each pixel in an image.

    • Images with an alpha channel can be composited more seamlessly allowing for smooth blending.

    The Image.alpha_composite() Method

    The Image.alpha_composite() method in Pillow is used for compositing two images using their alpha channels. It takes two Image objects as input and returns a new Image with the composited result.

    Here is the syntax and parameters of the Image.alpha_composite() method −

    PIL.Image.alpha_composite(image1, image2)
    

    Where,

    • image1 − The background image onto which the second image will be composited.

    • image2 − The foreground image that will be composited onto the background.

    Example - Compositing Two Images

    This example shows how to composite two images using Image.alpha_composite() method.

    main.py

    from PIL import Image
    
    #Open or create the background image
    background = Image.open("Images/decore.jpg").convert('RGBA')
    
    #Open or create the foreground image with transparency
    foreground = Image.open("Images/library_banner.jpg").convert('RGBA')
    
    #Ensure that both images have the same size
    if background.size != foreground.size:
        foreground = foreground.resize(background.size)
    
    #Perform alpha compositing
    result = Image.alpha_composite(background, foreground)
    
    # Display the resulting image
    result.show()
    

    Image to be used

    decore library_banner

    Output

    composite

    Adding Watermarks Using Compositing Images

    Adding a watermark to an image is one of the applications in image compositing tasks. You can overlay a watermark onto an image at a specific position and transparency. This is achieved by creating a new layer for the watermark and blending it with the base image using the Image.alpha_composite() method.

    Example - Adding Watermark to Image

    This example demonstrates how to to add a watermark onto an image using the Image.alpha_composite() method. The watermark image is placed on top of the base image with adjustable transparency.

    main.py

    from PIL import Image
    
    # Load the images and convert them to RGBA
    image = Image.open('Images/yellow_car.jpg').convert('RGBA')
    watermark = Image.open('Images/reading_img2.png').convert('RGBA')
    
    # Create an empty RGBA layer with the same size as the image
    layer = Image.new('RGBA', image.size, (0, 0, 0, 0))
    layer.paste(watermark, (20, 20))
    
    # Create a copy of the layer and adjust the alpha transparency
    layer2 = layer.copy()
    layer2.putalpha(128)
    
    # Merge the layer with its transparent copy using the alpha mask
    layer.paste(layer2, (0, 0), layer2)
    
    # Composite the original image with the watermark layer
    result = Image.alpha_composite(image, layer)
    
    # Display the resulting image
    result.show()
    

    Image to be used

    yellow_car.jpg

    Watermark Image

    reading_img2

    Output

    composite_2

    Python Pillow - Working With Alpha Channels



    An alpha channel in an image is a component that represents the level of transparency or opacity for each pixel. It is commonly used in RGBA images, where each pixel is defined by its Red, Green, Blue, and Alpha values. This channel determines how much of the background shows through an image. In simple terms we can say a pixel with an alpha value of 0 is fully transparent and while a pixel with an alpha value of 255 is fully opaque.

    Here are visual representations of an image with different transparency levels −

    working_with_alpha_channels_intro

    The following are the breakdown of key concepts related to alpha channels in Pillow −

    RGBA Mode

    • Images with an alpha channel are often represented in the RGBA mode.

    • Each pixel in an RGBA image has four components i.e. Red, Green, Blue and Alpha.

    Transparency Levels

    • The alpha channel values typically range from 0 to 255.

    • 0 indicates complete transparency i.e. fully see-through or invisible.

    • 255 indicate complete opacity i.e. fully opaque or not see-through.

    Accessing Alpha Channel

    We can access the alpha channel using the split() function of the Pillow Image module. This function is used to separate the individual color channels of an image. It breaks down an image into its constituent channels by allowing us to access and manipulate each channel separately.

    Splitting channels with split() function provides the flexibility to work with and manipulate individual color or alpha channels separately by enabling precise image adjustments and processing.

    When the split() function is called on an image object, it returns a tuple of individual channel images. For an RGBA image, the tuple includes the Red, Green, Blue, and Alpha channels. For grayscale or single-channel images split() function still returns four identical copies of the same channel. By accessing the alpha channel specifically, you can manipulate the transparency of an image directly.

    The following is the syntax and parameters of the of the split() function −

    r,g,b,a = image.split()
    

    Where,

    • image − This is the image object opened using Image.open() function.

    • r, g, b, a − These variables receive the separate bands representing Red, Green, Blue and Alpha i.e. transparency of channels respectively.

    Example - Accessing Alpha Channel

    In this example we are using the split() function to split and access the alpha channel.

    main.py

    from PIL import Image
    
    # Open an image
    img_obj = Image.open('Images/colordots.png')
    
    #Split the image into RGBA channels
    red, green, blue, alpha = img_obj.split()
    
    # Alpha (transparency) channel
    alpha.show()
    

    Input RGBA Image to be used

    colordots.jpg

    Output alpha channel

    splited_image_a

    Creating an Image with Alpha Channel

    To create an image with an alpha channel, we can use the new() function. This function provides options like mode, width, height and the RGBA values for customizing the image. The last argument's last value defines the transparency i.e. alpha of the image.

    Example - Creating Image with Alpha Channel

    In this example we will create an image with alpha channel using the new() funtion.

    main.py

    from PIL import Image
    
    # Create an RGBA image with Semi-transparent green
    image = Image.new('RGBA', (700, 300), (10, 91, 51, 100))  
    
    # Display the resultant image with alpha channel
    image.show()
    

    Output

    On executing the above program you will get output RGBA like below −

    image_with_alpha

    Modifying Alpha Channels

    The individual alpha values for pixels can be set using the putpixel() function to apply modifications to the alpha channel of an image.

    The putpixel() function of the Python Pillow is used to change the color of a single pixel at a specified position within an image. This function allows us to directly modify the color of a specific pixel by providing its coordinates and the desired color.

    The below is the syntax and parameters of the putpixel() function.

    image.putpixel((x, y), color)
    
    • image − This is the image object opened using Image.open() function.

    • (x, y) − These are the coordinates of the pixel where we want to set the color. x represents the horizontal position and y represents the vertical position.

    • color − The color value that we want to assign to the specified pixel. The format of the color value depends on the image mode.

    Example - Modifying Alpha Channel

    In this example we are using the putpixel() function of the pillow library for modifying the alpha values for pixels of the given input image.

    main.py

    from PIL import Image
    
    # Open an image
    image = Image.open("Images/colordots.png")
    width, height = image.size
    
    # Modify alpha values of pixels
    for y in range(height):
        for x in range(width):
            r, g, b, a = image.getpixel((x, y))
            image.putpixel((x, y), (r, g, b, int(a * 0.5)))  # Reduce alpha by 50%
    
    # Display the modified image
    image.show()
    

    Input Image

    colordots jpg

    Output modified image

    modified_alpha jpg

    Note

    • The putpixel() function directly modifies the image in memory. It is useful for making small modifications to individual pixels.

    • For large-scale pixel operations or more complex manipulations we have to consider using other Pillow functions that operate on larger regions or entire images for better performance.

    Example - Composite Images with Alpha Channel

    The Image.alpha_composite() function is used to composite two images with alpha channels. This function blends the images based on their alpha channels.

    In this example we are using the Image.alpha_composite() function for blending two images based on their alpha channels.

    main.py

    from PIL import Image
    
    # Open two images
    img1 = Image.open('Images/tp_logo.png')
    img2 = Image.open('Images/colordots_2.png')
    
    # Composite the images
    composite = Image.alpha_composite(img1, img2)
    
    # Display the result
    composite.show()
    

    Input Images −

    colordots_2 jpg tp_logo jpg

    Output alpha composited image −

    composite_image jpg

    Example - Saving Images with Alpha Channel

    To preserve transparency, save the image in a format that supports alpha channels such as PNG. Formats like JPEG do not support alpha channels and will discard transparency information. We can use the save() function available in pillow.

    In this example we are using the Image.save() function for saving an image with alpha channel.

    main.py

    from PIL import Image
    
    # Create a new image with alpha channel
    new_img = Image.new('RGBA', (700, 300), (255, 0, 0, 128)) 
    
    # Save the image with alpha channel
    new_img.save("Output_Images/new_img.png", "PNG")
    print("The image with alpha channel is saved.")
    

    Output

    After executing the above code, you will find the resulting PNG file 'new_img.png' saved in the current working directory −

    The image with alpha channel is saved.
    

    Python Pillow - Applying Perspective Transforms



    In Pillow applying perspective transforms involves altering the perspective or viewpoint of an image. This transformation modifies the position of the image's points in a way that simulates a change in perspective such as rotating, skewing or distorting the image.

    Perspective Transformation in Pillow

    The Pillow's transform() method allows you to apply differenyt types of transformations to an image. For perspective transforms a 3x3 transformation matrix is used to define the transformation. This matrix can represent operations like rotations, translations, scaling and shearing. For perspective transformation the matrix elements control how each pixel's coordinates change.

    Matrix Elements for Perspective Transform

    The matrix elements (a, b, c, d, e, f, g, h) define the transformation −

    • a and d represent scaling in the x and y directions.

    • b and c represent shearing or skewing.

    • e and f are translations along the x and y axes.

    • g and h are perspective coefficients.

    Applying Perspective Transforms

    We can use transform() directly with Image.PERSPECTIVE and pass four source points and four destination points to specify the transformation.

    Perspective transformations can distort images significantly. So carefully choose the transformation matrix or points to achieve the desired effect without excessive distortion.

    Applying perspective transforms in Pillow involves using transformation matrices or defining source and destination points to alter the image's perspective, simulating changes in angles, orientations or viewpoints. Understanding transformation matrices and point mappings is crucial for achieving the desired visual effects while avoiding excessive distortion or unwanted transformations in the image.

    The following are the syntax and parameters of the transform() method.

    transformed_image = image.transform(size, method, data, resample=0, fill=0)
    

    Where,

    • image − The Pillow Image object we want to transform.

    • size − A tuple representing the output size (width, height) of the transformed image.

    • method − Defines the type of transformation to be applied Image.AFFINE, Image.PERSPECTIVE or Image.QUAD, etc.

    • data − Transformation of data required based on the method used.

    • resample (optional) − The resampling method to use such as Image.BILINEAR, Image.NEAREST and Image.BICUBIC. Default value is 0 i.e. nearest neighbor.

    • fill (optional) − Fill color for areas outside the transformed image boundaries. Default is 0 i.e. black.

    Prepare data based on the Transformation method, for the Image.AFFINE transformation it requires a 6-element tuple that represents the affine transformation matrix. For perspective transformations, Image.PERSPECTIVE is used, which requires an 8-element tuple to represent the perspective transformation matrix. Additionally, Image.QUAD involves providing source and destination quadrilateral points for accurate perspective mapping.

    Example - Transforming an Image

    In this example we are performing the perspective transformation on the given input image by using the transform() method.

    main.py

    from PIL import Image
    import numpy
    
    def find_data(source, target):
        matrix = []
        for s, t in zip(source, target):
            matrix.append([t[0], t[1], 1, 0, 0, 0, -s[0]*t[0], -s[0]*t[1]])
            matrix.append([0, 0, 0, t[0], t[1], 1, -s[1]*t[0], -s[1]*t[1]])
        A = numpy.matrix(matrix, dtype=float)
        B = numpy.array(source).reshape(8)
        res = numpy.dot(numpy.linalg.inv(A.T * A) * A.T, B)
        return numpy.array(res).reshape(8)
    
    #Open an image
    image = Image.open("Images/logo_w.png")
    # image.show()
    
    #Define the transformation matrix for perspective transform
    coeffs = find_data(
        [(0, 0), (225, 0), (225, 225), (0, 225)],
        [(15, 115), (140, 20), (140, 340), (15, 250)])
    
    #Applying the perspective transformation
    transformed_image = image.transform((300, 400), Image.PERSPECTIVE, coeffs, Image.BICUBIC)
    
    #Save or display the transformed image
    transformed_image.save("Output_Images/transform.png")
    transformed_image.show()
    

    Output

    Following is the input image −

    logo_w.jpg

    On executing the above code, the following transformed image is displayed −

    transform

    Example - Applying Perspective Transformation to an Image

    Here this is another example of performing the perspective transformation to the another image with the matrix elements (a, b, c, d, e, f, g, h).

    main.py

    from PIL import Image
    
    #Open an image
    image = Image.open("Images/flowers.jpg")
    image.show()
    
    #Define the transformation matrix for perspective transform
    matrix = (10, 4, 11, -1, 5, 2, 1, -1)  
    
    #Apply the perspective transformation
    transformed_image = image.transform(image.size, Image.PERSPECTIVE, matrix)
    
    #Save or display the transformed image
    transformed_image.save("Output_Images/transform_image.jpg")
    transformed_image.show()
    

    Output

    On executing the above code you will get the following output −

    Input image:

     flowers input

    Output perspective transformed image:

    transform_image

    Note

    • The transform() method supports various transformation types and the transformation data required varies based on the chosen method.

    • It's crucial to provide the correct transformation data i.e. matrix or points based on the chosen transformation method to achieve the desired effect.

    • The transform() method in Pillow is versatile and allowing us to perform different types of geometric transformations on images offering flexibility in image manipulation and perspective alterations.

    Python Pillow - Adding Filters to an Image



    Image filtering is a fundamental technique for modifying and enhancing images. In image processing, filters are mathematical operations applied to an image to improve its quality, extract specific information, or alter its appearance. They work at the pixel level, applying mathematical operations to pixels within a defined neighborhood, often determined by structuring elements or footprints. These filters are used for a wide range of tasks, including smoothing, sharpening, and enhancing specific image features. They can be implemented through techniques like convolution and frequency domain manipulation.

    Python Pillow library provides the ImageFilter module with a predefined set of filters that can be applied to images using the Image.filter() method. These filters allow you to change the look and feel of images.

    The current version of the Python Pillow library offers a range of predefined image enhancement filters. Some of the filters include −

    • BLUR
    • CONTOUR
    • DETAIL
    • EDGE_ENHANCE
    • EDGE_ENHANCE_MORE
    • EMBOSS
    • FIND_EDGES
    • SHARPEN
    • SMOOTH
    • SMOOTH_MORE

    Applying Filter to an Image

    By using the Image.filter() method you can apply a specific filter to an image object. This method takes a filter kernel as a parameter and returns an Image object with the applied filter effect.

    Following is the syntax of the Image.filter() method −

    Image.filter(filter)
    

    This Image.filter() method accept only one parameter which is described below −

    • filter − The filter kernel to be applied.

    Example - Applying the BLUR Filter

    Here's an example of how to blur an input image using the ImageFilter.BLUR filter from the ImageFilter module.

    main.py

    from PIL import Image, ImageFilter
    
    # Open the input image 
    image = Image.open('Images/tp_logo_image.jpg')
        
    # Apply the BLUR filter to the image
    blurred_image = image.filter(filter=ImageFilter.BLUR)
    
    # Display the original and blurred images
    image.show()
    blurred_image.show()
    

    Input Image

    tp logo

    Output Image

    blur tp logo

    Example - Applying Predefined Image Enhancement Filters

    The following example demonstrates how to apply pillow predefined image enhancement filters to an input image.

    main.py

    from PIL import Image, ImageFilter
    import matplotlib.pyplot as plt
    
    # Open the input image
    image = Image.open('Images/flower1.jpg')
    
    # Apply CONTOUR filter to the image
    image_contour = image.filter(filter=ImageFilter.CONTOUR)
    
    # Apply DETAIL filter to the image
    image_detail = image.filter(filter=ImageFilter.DETAIL)
    
    # Apply EDGE_ENHANCE filter to the image
    image_edge = image.filter(filter=ImageFilter.EDGE_ENHANCE)
    
    # Apply EDGE_ENHANCE_MORE filter to the image
    image_edge_more = image.filter(filter=ImageFilter.EDGE_ENHANCE_MORE)
    
    # Apply EMBOSS filter to the image
    image_emboss = image.filter(filter=ImageFilter.EMBOSS)
    
    # Apply FIND_EDGES filter to the image
    image_edges = image.filter(filter=ImageFilter.FIND_EDGES)
    
    # Apply SMOOTH filter to the image
    image_smooth = image.filter(filter=ImageFilter.SMOOTH)
    
    # Apply SMOOTH_MORE filter to the image
    image_smooth_more = image.filter(filter=ImageFilter.SMOOTH_MORE)
    
    # Apply SHARPEN filter to the image
    image_sharpen = image.filter(filter=ImageFilter.SHARPEN)
    
    # Create a subplot for each filtered image and display it using Matplotlib
    fig, ax = plt.subplots(3, 3, figsize=(12, 10))
    
    # Original Image
    ax[0, 0].imshow(image)
    ax[0, 0].set_title("Original Image")
    
    # CONTOUR filter
    ax[0, 1].imshow(image_contour)
    ax[0, 1].set_title("CONTOUR")
    
    # DETAIL filter
    ax[0, 2].imshow(image_detail)
    ax[0, 2].set_title("DETAIL")
    
    # EDGE_ENHANCE filter
    ax[1, 0].imshow(image_edge)
    ax[1, 0].set_title("EDGE_ENHANCE")
    
    # EDGE_ENHANCE_MORE filter
    ax[1, 1].imshow(image_edge_more)
    ax[1, 1].set_title("EDGE_ENHANCE_MORE")
    
    # EMBOSS filter
    ax[1, 2].imshow(image_emboss)
    ax[1, 2].set_title("EMBOSS")
    
    # FIND_EDGES filter
    ax[2, 0].imshow(image_edges)
    ax[2, 0].set_title("FIND_EDGES")
    
    # SMOOTH filter
    ax[2, 1].imshow(image_smooth)
    ax[2, 1].set_title("SMOOTH")
    
    # SMOOTH_MORE filter
    ax[2, 2].imshow(image_smooth_more)
    ax[2, 2].set_title("SMOOTH_MORE")
    
    # Turn off ax for all subplots
    for a in ax.flatten():
       a.axis('off')
        
    plt.tight_layout()
    plt.show()
    

    Input Image

    flower1

    Output

    Filters Output

    Python Pillow - Convolution Filters



    In the context of image processing, Convolution involves applying a small matrix (known as convolution kernel) of values to an image. This process results in various filtering effects such as blurring, sharpening, embossing, and edge detection. Each value in the kernel represents a weight or coefficient. This kernel is applied to a corresponding neighborhood of pixels in the image to produce the output pixel value at the corresponding position in the output image.

    Python's Pillow library provides a specific class known as "kernel" within its ImageFilter module. This class is used to create convolution kernels of sizes that extend beyond the conventional 5x5 matrices.

    Creating the Convolution kernel

    To create a convolution kernel you can use the Kernel() class from the ImageFilter module.

    It's important to note that the current version of Pillow supports 33 and 55 integer and floating-point kernels. And these kernels apply exclusively to images in "L" and "RGB" modes.

    Following is the syntax of this ImageFilter.Kernel() class −

    class PIL.ImageFilter.Kernel(size, kernel, scale=None, offset=0)
    

    Here are the details of the class parameters −

    • size − Represents the kernel size, specified as (width, height). In the current version, the valid sizes are (3,3) or (5,5).

    • kernel − A sequence containing the kernel weights. The kernel is vertically flipped before applying it to the image.

    • scale − Denotes the scale factor. If provided, the result for each pixel is divided by this value. The default value is the sum of the kernel weights.

    • offset − Signifies an offset value. If provided, this value is added to the result after being divided by the scale factor.

    Example - Applying a Convolution Kernel Filter

    This example demonstrates how to apply a convolution kernel filter to an image using the Image.filter() method.

    main.py

    from PIL import Image, ImageFilter
    
    # Create an image object
    original_image = Image.open('Images/yellow_car.jpg')
    
    # Apply the Kernel filter
    filtered_image = original_image.filter(ImageFilter.Kernel((3, 3), (0, -1, 0, -1, 5, -1, 0, -1, 0)))
    
    # Display the original image 
    original_image.show()
    
    # Display the filtered image
    filtered_image.show()
    

    Input Image

    yellow car

    Output

    Output of the convolution kernel filter −

    convolution kernel filter

    Example - Applying an Emboss Convolution Filter

    Here's an example of applying a 5x5 emboss convolution kernel filter to an image.

    main.py

    from PIL import Image, ImageFilter
    
    # Create an image object
    original_image = Image.open('Images/yellow_car.jpg')
    
    # Define a 5x5 convolution kernel
    kernel_5x5 = [-2,  0, -1,  0,  0,
       0, -2, -1,  0,  0,
       -1, -1,  1,  1,  1,
       0,  0,  1,  2,  0,
       0,  0,  1,  0,  2]
    
    # Apply the 5x5 convolution kernel filter
    filtered_image = original_image.filter(ImageFilter.Kernel((5, 5), kernel_5x5, 1, 0))
    
    # Display the original image 
    original_image.show()
    
    # Display the filtered image
    filtered_image.show()
    

    Input Image

    yellow car

    Output Image

    Output of the convolution kernel filter of size 5X5 −

    imagefilter kernel

    Python Pillow - Blurring an Image



    Blurring an Image is a fundamental concept in image processing, used to reduce the level of detail or sharpness in an image. The primary purpose of blurring is to make an image appear smoother or less sharp. Blurring can be achieved through various mathematical operations, convolution kernels, or filters.

    Python's Pillow library offers several standard image filters within the ImageFilter module to perform the different blurring operations on the image by calling the image.filter() method. In this tutorial we will see different image blurring filters provided by the ImageFilter module.

    Applying Blur Filter to an Image

    Blurring an image can be done by using the ImageFilter.BLUR filter, which is one of the built-in filter options available in the current version of the Pillow library and is used to create a blurred effect in the image.

    Following are the steps for applying image blurring −

    • Load the input image using the Image.open() function.

    • Apply the filter() function to the loaded Image object and provide ImageFilter.BLUR as an argument to the function. The function will return the blurred image as a PIL.Image.Image object.

    Following is the input image used in all the examples of this chapter.

    yellow car

    Example - Blurring an Image

    Here is the example using the Image.filter() method with ImageFilter.BLUR kernel filter.

    from PIL import Image, ImageFilter
    
    # Open an existing image
    original_image = Image.open('Images/yellow_car.jpg')
    
    # Apply a blur filter to the image
    blurred_image = original_image.filter(ImageFilter.BLUR)
    
    # Display the original image 
    original_image.show()
    
    # Display the blurred mage
    blurred_image.show()
    

    Output Image

    blur car

    Applying the BoxBlur Filter

    The BoxBlur filter is used to blur an image by setting each pixel's value to the average value of the pixels within a square box that extends a specified number of pixels in each direction. For this yo can use the BoxBlur() class from the Pillow's ImageFilter module.

    Following is the syntax of the ImageFilter.BoxBlur() class −

    class PIL.ImageFilter.BoxBlur(radius)
    

    The PIL.ImageFilter.BoxBlur() class accepts a single parameter −

    • radius − This parameter specifies the size of the square box used for blurring in each direction. It can be provided as either a sequence of two numbers (for the x and y directions) or a single number that applies to both directions.

    If radius is set to 1, it takes the average of the pixel values within a 3x3 square box (1 pixel in each direction, resulting in 9 pixels in total). A radius value of 0 doesn't blur the image and returns an identical image.

    Example - Box Blur an Image

    Here's an example that demonstrates how to use the BoxBlur() filter for image blurring.

    main.py

    from PIL import Image, ImageFilter
    
    # Open an existing image
    original_image = Image.open('Images/yellow_car.jpg')
    
    # Apply a Box Blur filter to the image
    box_blurred_image = original_image.filter(ImageFilter.BoxBlur(radius=3))
    
    # Display the Box Blurred image
    box_blurred_image.show()
    

    Output Image

    imagefilter boxblur

    Applying the Gaussian Blur to an Image

    The GaussianBlur filter is used to blur an image by applying a Gaussian blur, which is a specific type of blur that approximates a Gaussian distribution. This can be done by using the Pillow's ImageFilter.GaussianBlur() class.

    Below is the syntax of the ImageFilter.GaussianBlur() class −

    class PIL.ImageFilter.GaussianBlur(radius=2)
    

    The ImageFilter.GaussianBlur() class accepts a single parameter −

    • radius − This parameter specifies the standard deviation of the Gaussian kernel. The standard deviation controls the extent of blurring. You can provide it as either a sequence of two numbers (for the x and y directions) or a single number that applies to both directions.

    Example - Applying Gaussian Blur to an Image

    Here's an example that demonstrates how to use the GaussianBlur() class for image blurring.

    main.py

    from PIL import Image, ImageFilter
    
    # Open an existing image
    original_image = Image.open('Images/yellow_car.jpg')
    
    # Apply a Gaussian Blur filter to the image
    gaussian_blurred_image = original_image.filter(ImageFilter.GaussianBlur(radius=2))
    
    # Display the Gaussian Blurred image
    gaussian_blurred_image.show()
    

    Output Image

    imagefilter gaussianblur

    Python Pillow - Detecting Edges



    Edge detection is the process of identifying these boundaries or contours in an image using mathematical algorithms. The edge detection aims to locate the points in the image where the intensity changes suddenly, which usually corresponds to an edge or a boundary between two regions. In general, an edge defined as a boundary or a contour between two distinct regions in an image. These regions can differ in intensity, color, texture, or any other visual feature. Edges can represent important features in an image, such as object boundaries, shapes, and textures.

    Edge detection is an essential step in many image-processing applications, such as object recognition, segmentation, tracking, and enhancement. In this tutorial, we will see different approaches to detect edges in an image using the Python pillow library.

    Applying Edge Detection Filter to an Image

    Detecting edges in an image can be done by using the ImageFilter.FIND_EDGES filter, which is one of the built-in filter options available in the current version of the Pillow library to detect edges in the image.

    Following are the steps for detecting the edges in the image −

    • Load the input image using the Image.open() function.

    • Apply the filter() function to the loaded Image object and provide ImageFilter.FIND_EDGES as an argument to the function. The function will return the Output detected edges as a PIL.Image.Image object.

    Example - Finding Edges

    The following example demonstrates how to use the ImageFilter.FIND_EDGES filter kernel with the filter() method to detect the edges in an image.

    main.py

    from PIL import Image, ImageFilter
    
    # Open the image
    image = Image.open('Images/compass.jpg')
    
    # Apply edge detection filter
    edges = image.filter(ImageFilter.FIND_EDGES)
    
    # Display the original image
    image.show()
    
    # Display the edges-detected image
    edges.show()
    

    Input Image

    compass

    Output Image

    Output detected edges −

    imagefilter find edges

    Example - Flattening the Edges

    Here is an example that uses the ImageFilter.FIND_EDGES filter kernel to detect edges in the image. And then it applies ImageFilter.MaxFilter() class to flatten the detected edges.

    main.py

    import matplotlib.pyplot as plt
    from PIL import Image, ImageFilter
    
    # Open the image and convert it to grayscale
    im = Image.open('Images/compass.jpg').convert('L')
    
    # Detect edges
    edges = im.filter(ImageFilter.FIND_EDGES)
    
    # Make fatter edges
    fatEdges = edges.filter(ImageFilter.MaxFilter)
    
    # Make very fat edges
    veryFatEdges = edges.filter(ImageFilter.MaxFilter(7))
    
    # Create subplots for displaying the images
    fig, axes = plt.subplots(2, 2, figsize=(12, 10))
    ax = axes.ravel()
    
    # Original image
    ax[0].imshow(im, cmap='gray')
    ax[0].set_title('Original')
    
    # Detected edges
    ax[1].imshow(edges, cmap='gray')
    ax[1].set_title('Edges')
    
    # Fatter edges
    ax[2].imshow(fatEdges, cmap='gray')
    ax[2].set_title('Fatter Edges')
    
    # Very fat edges
    ax[3].imshow(veryFatEdges, cmap='gray')
    ax[3].set_title('Very Fat Edges')
    
    for ax in axes.flatten():
       ax.axis('off')
    
    # Display the images
    plt.tight_layout()
    plt.show()
    

    Output Image

    imagefilter maxfilter

    Example - Detecting Edges using the ImageFilter.Kernel() Class

    This class is used to create a convolution kernel.

    In this approach we will define a 3X3 convolution kernel with some specified kernel values (-1, -1, -1, -1, 8, -1, -1, -1, -1). We will perform edge detection on an image.

    The following example demonstrates how to perform edge detection on an image using the convolution matrix and the ImageFilter.kernel() class.

    main.py

    from PIL import Image, ImageFilter
    
    # Open the image and convert it to grayscale
    image = Image.open('Images/compass.jpg').convert('L')
    
    # Calculate edges using a convolution matrix
    kernel = ImageFilter.Kernel((3, 3), (-1, -1, -1, -1, 8, -1, -1, -1, -1), scale=1, offset=0)
    edges = image.filter(kernel)
    
    # Display the original image
    image.show()
    
    # Display the edges
    edges.show()
    

    Input Image

    image_convertto grayscale

    Output Image

    Output detected edges −

    detected edges

    Python Pillow - Embossing Images



    In general, embossing used for creating raised relief images on paper or cardstock to achieve a three-dimensional appearance, was notably used by the British postal service during the 19th century to add an elegant touch to stamps. This process involves raising certain parts of the image, design, or text to create a three-dimensional effect.

    In image processing and computer graphics, image embossing is a technique where each pixel in an image is transformed into either a highlighted or shadowed version, depending on the original image's light and dark boundaries. Areas with low contrast are replaced by a gray background. The resulting embossed image effectively represents the rate of color change at each location within the original image. Applying an embossing filter to an image can often produce an output resembling a paper or metal-embossed rendition of the original image, hence its name.

    Python's Pillow library offers several standard image filters within the ImageFilter module to perform the different filter operations on the image by calling the image.filter() method. In this tutorial, we will see the working of the embossing filter provided by the ImageFilter module.

    Applying ImageFilter.EMBOSS kernel filter with the Image.filter() method

    The ImageFilter.EMBOSS filter is one of the built-in filter options available in the current version of the Pillow library and is used to create an embossed effect in the image.

    Following are the steps for applying image embossing −

    • Load the input image using the Image.open() function.

    • Apply the filter() function to the loaded Image object and provide ImageFilter.EMBOSS as an argument to the function. The function will return the embossed image as a PIL.Image.Image object.

    Example - Apply Embossing Effect

    Here is an example using the Image.filter() method with ImageFilter.EMBOSS kernel filter.

    main.py

    from PIL import Image, ImageFilter
    
    # Load an input image
    input_image = Image.open("Images/tp_logo_image.jpg")
    
    # Apply an emboss effect to the image
    embossed_result = input_image.filter(ImageFilter.EMBOSS)
    
    # Display the input image
    input_image.show()
    
    # Display the modified image with the emboss effect
    embossed_result.show()
    

    Input Image

    tp logo

    Output Image

    Output filtered image with emboss effect −

    imagefilter emboss

    Customizing the EMBOSS filter to add depth and azimuth to the embossed image

    In the source code of the pillow library, we can observe the EMBOSS class in the "ImageFilter.py," module. This class represents the embossing filter and provides a basic way to create an embossed effect on an image.

    # Embossing filter.
    class EMBOSS(BuiltinFilter):
       name = "Emboss"
       # fmt: off
       filterargs = (3, 3), 1, 128, (
          -1, 0, 0,
          0,  1, 0,
          0,  0, 0,
       )
    

    The filter operates by applying a matrix to the image pixel by pixel. The matrix contains values that determine the transformation applied to each pixel. By modifying the matrix, you can control the azimuth and strength of the embossing effect.

    The matrix is a 3x3 grid where each element corresponds to the current pixel and its surrounding pixels. The central value represents the current pixel being processed. The filter combines these values based on their weights in the matrix to create the transformed pixel. You can customize the filter by adjusting the scale and offset parameters, which influence the overall strength of the effect.

    Example - Custom Emboss Effect

    Here is an example that demonstrates how to apply a custom emboss filter to an image, allowing you to control the appearance of the emboss effect by adjusting various parameters.

    main.py

    from PIL import Image, ImageFilter
    
    # Open the input image 
    image = Image.open('Images/tp_logo_image.jpg')
    
    # modify the filterargs such as scale, offset and the matrix
    ImageFilter.EMBOSS.filterargs=((3, 3), 2, 150, (0, 0, 0, 0, 1, 0, -2, 0, 0))
        
    # Apply an emboss effect to the image
    embossed_result = image.filter(ImageFilter.EMBOSS)
    
    # Display the input image
    image.show()
    
    # Display the modified image with the emboss effect
    embossed_result.show()
    

    Input Image

    tp logo

    Output Image

    Output filtered image with custom emboss effect −

    emboss effect

    Python Pillow - Enhancing Edges of an Image



    Enhancing edges is a commonly used technique in image processing and computer vision to improve the interpretation and analysis of images. It refers to the process of emphasizing or highlighting the boundaries between different objects or regions in an image. And it aims to improve the visibility of edges, making them more distinct and prominent.

    Python Pillow library provides the ImageFilter module with a predefined set of filters that can be applied to images using the Image.filter() method. The current version of the library offers two predefined image enhancement filters namely EDGE_ENHANCE and EDGE_ENHANCE_MORE to enhance edges in an image.

    Enhancing Edges using the ImageFilter.EDGE_ENHANCE Kernel

    This ImageFilter.EDGE_ENHANCE kernel filter is designed to Enhance the edges in the image.

    Following are the steps for enhancing the edges in the image −

    • Load the input image using the Image.open() function.

    • Apply the filter() function to the loaded Image object and Provide ImageFilter.EDGE_ENHANCE as an argument to the Image.filter() function, then it returns a PIL.Image.Image object with enhanced edges.

    Example - Enhancing Edges

    Here's an example that demonstrates how to use the ImageFilter.EDGE_ENHANCE filter kernel to enhance edges in an image.

    main.py

    from PIL import Image, ImageFilter
    
    # Open the input image
    image = Image.open('Images/flower1.jpg')
    
    # Apply edge enhancement filter
    enhanced_image = image.filter(ImageFilter.EDGE_ENHANCE)
    
    # Display the original and enhanced images
    image.show()
    enhanced_image.show()
    

    Input Image

    pink_flower.jpg

    Output Image

    Output image with enhanced edges −

    imagefilter edge enhance

    Enhancing Edges using the EDGE_ENHANCE_MORE Kernel

    This approach works similar to the EDGE_ENHANCE filter, but it applies a stronger enhancement to edges.

    Example - Applying EDGE_ENHANCE_MORE filter

    Here's an example that demonstrates how to use the EDGE_ENHANCE_MORE filter kernel to enhance edges in an image more aggressively.

    from PIL import Image, ImageFilter
    
    # Open the input image
    image = Image.open('Images/flower1.jpg')
    
    # Apply the EDGE_ENHANCE_MORE filter to the image
    enhanced_image = image.filter(ImageFilter.EDGE_ENHANCE_MORE)
    
    # Display the original and enhanced images
    image.show()
    enhanced_image.show()
    

    Input Image

    pink_flower.jpg

    Output Image

    Output image after applying the EDGE_ENHANCE_MORE filter to the input image −

    edge enhance more

    Python Pillow - Unsharp Mask Filter



    Unsharp masking is a widely used image sharpening technique in image processing. The fundamental concept behind unsharp masking involves using a softened or unsharp version of a negative image to create a mask for the original image. This unsharp mask is subsequently merged with the original positive image, resulting in a less blurry version of the original image, making it clearer.

    The Python pillow(PIL) library provides a class called UnsharpMask() within its ImageFilter module for the application of the Unsharp Masking filter to images.

    The UnsharpMask Filter

    The ImageFilter.UnsharpMask() class represents an unsharp mask filter, which is used to enhance image sharpness.

    Following is the syntax of the ImageFilter.UnsharpMask() class −

    class PIL.ImageFilter.UnsharpMask(radius=2, percent=150, threshold=3)
    

    Where,

    • radius − This parameter controls the blur radius. Radius affects the size of the edges to be enhanced. A smaller radius sharpens smaller details, while a larger radius can create light halos around objects. Adjusting the radius and amount affects each other; decreasing one allows the other to have a greater impact.

    • percent − It determines the strength of the unsharp mask in percentage. Percentage controls the strength or magnitude of the sharpening effect. It determines how much contrast is added at the edges of objects. A higher amount results in a more pronounced sharpening effect, making edge borders darker and lighter. It does not impact the width of the edge rims.

    • threshold − Threshold controls the minimum change in brightness that gets sharpened. It decides how different adjacent tonal values need to be for the filter to take action. A higher threshold prevents smooth areas from becoming speckled. Lower values sharpen more, while higher values spare lower-contrast areas.

    Example - Using Unsharp Mask

    The following example applies the unsharp mask filter to an image using the ImageFilter.UnsharpMask() class and the Image.filter() method with default values.

    main.py

    from PIL import Image, ImageFilter
    
    # Open the image 
    original_image = Image.open('Images/flower1.jpg')
    
    # Apply the Unsharp Mask filter with default parameter values
    sharpened_image = original_image.filter(ImageFilter.UnsharpMask())
    
    # Display the original image
    original_image.show()
    
    # Display the sharpened image
    sharpened_image.show()
    

    Output

    Input image −

    zinnia flower

    Output image after applying the unsharp mask filter with default parameter values −

    imagefilter unsharpmask

    Example - Using Custom Unsharp Mask

    Here's another example that applies the Unsharp Mask filter to an image using different parameter values.

    main.py

    from PIL import Image, ImageFilter
    
    # Open the image using Pillow
    original_image = Image.open('Images/flower1.jpg')
    
    # Apply the Unsharp Mask filter with custom parameters
    sharpened_image = original_image.filter(ImageFilter.UnsharpMask(radius=4, percent=200, threshold=3))
    
    # Display the original image
    original_image.show()
    
    # Display the sharpened image
    sharpened_image.show()
    

    Output

    Input image −

    zinnia flower

    Output image after applying the unsharp mask filter with custom parameter values −

    unsharpmask

    Python Pillow - Enhancing Constract



    Enhancing contrast refers to the process of improving the visibility and quality of an image. It is an image processing technique that involves increasing the difference between the various elements within an image, such as objects, shapes, edges, and textures, by adjusting the distribution of intensity values or colors. This technique is widely used in fields such as medical imaging, computer vision, remote sensing, and photography to improve image quality and obtain more detailed visual information.

    The Python Pillow (PIL) library offers the Contrast() class within its ImageEnhance module, for the application of contrast enhancement to images.

    Enhancing Contrast of an Image

    To adjust the contrast of an image, you can apply ImageEnhance.Contrast() class to an image object with the enhancment factor. It controls the contrast of an image, much like adjusting the contrast on a television set.

    Below is the syntax of the ImageEnhance.Contrast() class −

    class PIL.ImageEnhance.Contrast(image)
    

    Following are the steps to achieve contrast enhancement of an image −

    • Create a contrast object using the ImageEnhance.Contrast() class.

    • Then apply the enhancement factor with the help of contrast_object.enhance() method.

    An enhancement factor is a floating-point value passed to the common single interface method, enhance(factor), which plays an important role in adjusting image contrast. When a factor of 0.0 is used, it will produce a solid grey image. A factor of 1.0 will give the original image, and when greater values are used, the contrast of the image is increased, making it visually more distinct.

    Example

    The following example demonstrates how to achieve a highly contrasted image using the PIL.ImageEnhance module.

    main.py

    from PIL import Image, ImageEnhance
    
    # Open the input image 
    image = Image.open('Images/flowers.jpg')
    
    # Create an ImageEnhance object for adjusting contrast
    enhancer = ImageEnhance.Contrast(image)
    
    # Display the original image
    image.show()
    
    # Enhance the contrast by a factor of 2 and display the result
    enhancer.enhance(2).show()
    

    Input Image

    sky flowers

    Output Image

    Output a highly contrasted version of the input image −

    image enhance contrast

    Example - Reducing Contract of an Image

    To reduce the contrast of an image, you can use a contrast enhancement factor less than 1. Here's an example illustrating the creation of a low-contrast version of the input image using the PIL.ImageEnhance.Contrast class.

    main.py

    from PIL import Image, ImageEnhance
    
    # Open the input image 
    image = Image.open('Images/flowers.jpg')
    
    # Create an ImageEnhance object for adjusting contrast
    enhancer = ImageEnhance.Contrast(image)
    
    # Display the original image
    image.show()
    
    # Reduce the contrast by a factor of 0.5 and display the result
    enhancer.enhance(0.5).show()
    

    Input Image

    sky flowers

    Output Image

    Output a low contrasted version of the input image −

    low contrasted image

    Python Pillow - Enhancing Sharpness



    Sharpness is a key factor in defining the clarity and detail in a photograph, and it serves as a valuable tool for emphasizing texture and visual impact.

    Enhancing Sharpness is an image processing technique used to enhance an image's edges, details, and contrast, resulting in a clearer and more vivid appearance. This process can significantly enhance the quality and visibility of images that are blurry, noisy, or distorted because of factors such as camera shake, low resolution, or compression.

    Enhancing Sharpness of an Image

    In Python Pillow library, enhancing and adjusting the sharpness of an image can be achived by using the ImageEnhance.Sharpness() class. It allows you to adjust the sharpness of an image by applying the enhancement factor.

    Below is the syntax of the ImageEnhance.Sharpness() class −

    class PIL.ImageEnhance.Sharpness(image)
    

    An enhancement factor represented as a floating-point value, is passed as an argument to the common single interface method, enhance(factor). This factor plays an important in adjusting the image's sharpness. Using a factor of 0.0 can lead to a completely blurred image, while a factor of 1.0 gives the original image. And higher values enhance the image's sharpness.

    Following are the steps to achieve Sharpness Enhancement of an image −

    • Create a Sharpness enhancer object using the ImageEnhance.Sharpness() class.

    • Then apply the enhancement factor to the enhancer object using the enhance() method.

    Example - Enhancing Sharpness of an Image

    Here's an example that demonstrates how to adjust the sharpness of an image by specifying a factor.

    main.py

    from PIL import Image, ImageEnhance
    
    # Open an image file
    image = Image.open('Images/butterfly_and_flowers.jpg')
    
    # Create a Sharpness object
    Enhancer = ImageEnhance.Sharpness(image)
    
    # Display the original image
    image.show()
    
    # Enhance the sharpness with a factor of 4.0
    sharpened_image = enhancer.enhance(4.0)
    
    # Display the sharpened image
    sharpened_image.show()
    

    Output

    The Input image −

    butterfly and flowers

    The output sharpness enhanced image −

    sharpness image

    Example - Blurring an Image

    In this example, you can obtain a blurred version of the input image by setting the enhancement factor to a value close to zero.

    main.py

    from PIL import Image, ImageEnhance
    
    # Open an image file
    image = Image.open('Images/butterfly.jpg')
    
    # Create a Sharpness object
    enhancer = ImageEnhance.Sharpness(image)
    
    # Display the original image
    image.show()
    
    # Decrease the sharpness by using a factor of 0.05
    sharpened_image = enhancer.enhance(0.05)
    
    # Display the sharpened image
    sharpened_image.show()
    

    Output

    The input image −

    butterfly and flowers

    The output blurred version of the input image −

    blured butterfly

    Python Pillow - Enhancing Color



    Enhancing color is an image processing technique that focuses on improving the visual appeal and quality of a digital image by fine-tuning the balance and saturation of its colors. The objective of image color enhancement is to get finer image details while highlighting the useful information. This technique is especially useful in scenarios where images have poor illumination conditions, resulting in darker and low-contrast appearances that require refinement. This technique is widely used in various fields, including graphic design, photography, and digital art, to enhance the visual impact of images.

    The Python Pillow library (PIL) offers the Color() class within its ImageEnhance module, which enables you to apply color enhancement to images.

    Enhancing Color of an Image

    To enhance the color of an image using the Python Pillow library, you can use the ImageEnhance.Color() class, which allows you to adjust the color balance of an image, just as controls on a color TV set.

    Following is the syntax of the ImageEnhance.Color() class −

    class PIL.ImageEnhance.Color(image)
    

    An enhancement factor represented as a floating-point value, is passed as an argument to the common single interface method, enhance(factor). This factor plays an important role in adjusting the color balance. A factor of 0.0 will give a black and white image. A factor of 1.0 gives the original image.

    Following are the steps to achieve color enhancement of an image −

    • Create a color enhancer object using the ImageEnhance.Color() class.

    • Then apply the enhancement factor to the enhancer object using the enhance() method.

    Example - Enhancing Color by 3.0

    Here is an example that enhances the color of an image with a factor of 3.0.

    main.py

    from PIL import Image, ImageEnhance
    
    # Open an image file
    image = Image.open('Images/tajmahal.jpg')
    
    # Create a Color object
    color_enhancer = ImageEnhance.Color(image)
    
    # Display the original image
    image.show()
    
    # Enhance the color with a factor of 3.0
    colorful_image = color_enhancer.enhance(3.0) 
    
    # Display the enhanced color image
    colorful_image.show()
    

    Output

    Input image −

    tajmahal

    Output highly color enhanced image −

    highly color enhanced

    Example - Enhancing Image by 0.0

    Here is an example that enhances the color of an image with a lower enhancement factor(0.0).

    main.py

    from PIL import Image, ImageEnhance
    
    # Open an image file
    image = Image.open('Images/tajmahal.jpg')
    
    # Create a Color object
    color_enhancer = ImageEnhance.Color(image)
    
    # Display the original image
    image.show()
    
    # Enhance the color with a factor of 0.0
    colorful_image = color_enhancer.enhance(0.0) 
    
    # Display the enhanced color image
    colorful_image.show()
    

    Output

    Input image −

    tajmahal

    Output color enhanced image with a factor of 0.0 −

    image enhance zero

    Python Pillow - Enhancing Color Balance



    Correcting color balance, in the context of image processing, refers to the adjustment of the intensities of different colors within an image to achieve a desired visual outcome. This adjustment typically involves the primary colors of red, green, and blue and is aimed at rendering specific colors, especially neutral colors like white or gray, correctly. Correct color balance ensures that the colors in an image appear as they would in the real world, making it look more naturalistic and pleasing to the human eye.

    The Python pillow library provides several options to correct the color balance of an image. Let's explore them below.

    Correcting Color Balance of an Image

    Correcting or adjusting an image's color balance can simply be done by using the PIL.ImageEnhance.Color() class. This class provides the ability to fine-tune the color balance of an image by changing the enhancement factor.

    Below is the syntax of the ImageEnhance.Color() class −

    class PIL.ImageEnhance.Color(image)
    

    An enhancement factor is a floating-point value passed to the common single interface method, enhance(factor), which plays an important role in adjusting image color balance. When a factor of 0.0 is used, it will produce a solid grey image. A factor of 1.0 will give the original image.

    Following are the steps to adjust the color balance of an image −

    • Create a color enhancer object using the ImageEnhance.Color() class.
    • Then apply the enhancement factor using the enhancer_object.enhance() method.

    Example - Adjusting Color Balance of an Image

    Here is an example that uses the PIL.ImageEnhance.Color class to adjust the color balance of an image.

    from PIL import Image, ImageEnhance
    
    # Open the image
    input_image = Image.open("Images/tajmahal.jpg")
    
    # Create a ColorEnhance object
    color_enhancer = ImageEnhance.Color(input_image)
    
    # Adjust the color balance by setting the enhancement factor
    enhancement_factor = 1.5
    color_balanced_image = color_enhancer.enhance(enhancement_factor)
    
    # Display the original and color balanced images 
    input_image.show()
    color_balanced_image.show()
    

    Input Image

    tajmahal

    Output Color Balanced Image

    color balanced image

    Correcting Color Balance using the Point Transforms

    Here is another approach of applying point transforms to color channels of an image for adjusting the color balance of an image. Point transforms can generally be used to adjust various aspects of an image, including color balance, brightness, and contrast. This can be done by using the point() method, it helps to Process the individual bands/ channels of an image.

    Example - Point Transformations

    Here is an example that demonstrates the application of point transforms to correct the color balance of an image.

    main.py

    from PIL import Image
    
    # Open the image
    input_image = Image.open("Images/tree.jpg")
    
    # Extract the red (R), green (G), and blue (B) channels
    red_channel, green_channel, blue_channel = input_image.split()
    
    # Adjust the color balance by scaling the intensity of each channel
    # Increase green intensity
    green_channel = green_channel.point(lambda i: i * 1.2)
    
    # Decrease blue intensity

    Python Pillow - Removing Noise



    Removing noise, also referred to as denoising, involves the process of reducing unwanted artifacts in an image. Noise in an image typically appears as random variations in brightness or color that are not part of the original scene or subject being photographed. The goal of image denoising is to enhance the quality of an image by eliminating or reducing these unwanted and distracting artifacts, making the image cleaner, and more visually appealing.

    The Python pillow library offers a range of denoising filters, allowing users to remove noise from noisy images and recover the original image. In this tutorial, we will explore GaussianBlur and Median filters as effective methods for noise removal.

    Removing the noise using the GaussianBlur filter

    Removing the noise from an image using the gaussian blur filter is a widely used technique. This technique is works by applying a convolution filter to the image to smooth out the pixel values.

    Example - Using Gaussian Blur Filter

    Here is an example that uses the ImageFilter.GaussianBlur() filter to remove the noise from an RGB image.

    main.py

    from PIL import Image, ImageFilter
    
    # Open a Gaussian Noised Image  
    input_image = Image.open("Images/GaussianNoisedImage.jpg").convert('RGB')
    
    # Apply Gaussian blur with some radius
    blurred_image = input_image.filter(ImageFilter.GaussianBlur(radius=2))
    
    # Display the input and the blurred image
    input_image.show()
    blurred_image.show()
    

    Input Noised Image

    GaussianNoisedImage

    Output Noise Removed Image

    blurred image tp

    Example - Removing the noise using the Median Filter

    The median filter is an alternative approach for noise reduction, particularly useful for the images where the noise points are like small and scattered. This function operates by replacing each pixel value with the median value within its local neighborhood. the Pillow library provides the ImageFilter.MedianFilter() filter for this purpose.

    Following example removes the noice from an image using the ImageFilter.MedianFilter().

    main.py

    from PIL import Image, ImageFilter
    
    # Open an image
    input_image = Image.open("Images/balloons_noisy.jpg")
    
    # Apply median filter with a kernel size 
    filtered_image = input_image.filter(ImageFilter.MedianFilter(size=3))
    
    # Display the input and the filtered image
    input_image.show()
    filtered_image.show()
    

    Input Noisy Image

    balloons noisy

    Output Median Filtered Image

    filtered image balloons

    Exampl - Reducing Noise in Grayscale Image

    This example demonstrates the reduction of salt-and-pepper noise in a grayscale image. This can be done by using a median filter, enhancing the contrast to improve visibility, and subsequently converting the image to binary mode for display.

    main.py

    from PIL import Image, ImageEnhance, ImageFilter, ImageOps
    
    # Open the image and convert it to grayscale
    input_image = ImageOps.grayscale(Image.open('Images/salt-and-pepper_noise.jpg'))
    
    # Apply a median filter with a kernel size of 5 to reduce noise
    filtered_image = input_image.filter(ImageFilter.MedianFilter(5))
    
    # Enhance the contrast of the filtered image
    contrast_enhancer = ImageEnhance.Contrast(filtered_image)
    high_contrast_image = contrast_enhancer.enhance(3)
    
    # Convert the image to binary
    binary_image = high_contrast_image.convert('1')
    
    # Display the input and processed images
    input_image.show()
    binary_image.show()
    

    Input Noisy Image

    salt and pepper noise

    Output Median Filtered Image

    median filtered blue_channel = blue_channel.point(lambda i: i * 0.8) # Merge the channels back into an RGB image corrected_image = Image.merge("RGB", (red_channel, green_channel, blue_channel)) # Display the input and corrected images input_image.show() corrected_image.show()

    Input Image

    tajmahal

    Output Image

    Output Color Balanced Image −

    tree

    Example - Using Transformation Matrix

    The following example adjusts the color balance of an image by applying a transformation matrix to its color channels.

    main.py

    from PIL import Image
    
    # Open the input image
    input_image = Image.open("Images/tajmahal.jpg")
    
    # Define a transformation matrix to adjust color channels
    # Multiply R (red) by 1.2, leaving G (green) and B (blue) unchanged
    transformation_matrix = (1.5, 0, 0, 0,
       0, 1, 0, 0,
       0, 0, 1, 0)
    
    # Apply the color channel transformation and create the corrected image
    corrected_image = input_image.convert("RGB", transformation_matrix)
    
    # Show the original and corrected images
    input_image.show()
    corrected_image.show()
    

    Input Image

    tajmahal

    Output Image

    Output Color Balanced Image −

    tajmahal balance color

    Python Pillow - Removing Noise



    Removing noise, also referred to as denoising, involves the process of reducing unwanted artifacts in an image. Noise in an image typically appears as random variations in brightness or color that are not part of the original scene or subject being photographed. The goal of image denoising is to enhance the quality of an image by eliminating or reducing these unwanted and distracting artifacts, making the image cleaner, and more visually appealing.

    The Python pillow library offers a range of denoising filters, allowing users to remove noise from noisy images and recover the original image. In this tutorial, we will explore GaussianBlur and Median filters as effective methods for noise removal.

    Removing the noise using the GaussianBlur filter

    Removing the noise from an image using the gaussian blur filter is a widely used technique. This technique is works by applying a convolution filter to the image to smooth out the pixel values.

    Example - Using Gaussian Blur Filter

    Here is an example that uses the ImageFilter.GaussianBlur() filter to remove the noise from an RGB image.

    main.py

    from PIL import Image, ImageFilter
    
    # Open a Gaussian Noised Image  
    input_image = Image.open("Images/GaussianNoisedImage.jpg").convert('RGB')
    
    # Apply Gaussian blur with some radius
    blurred_image = input_image.filter(ImageFilter.GaussianBlur(radius=2))
    
    # Display the input and the blurred image
    input_image.show()
    blurred_image.show()
    

    Input Noised Image

    GaussianNoisedImage

    Output Noise Removed Image

    blurred image tp

    Example - Removing the noise using the Median Filter

    The median filter is an alternative approach for noise reduction, particularly useful for the images where the noise points are like small and scattered. This function operates by replacing each pixel value with the median value within its local neighborhood. the Pillow library provides the ImageFilter.MedianFilter() filter for this purpose.

    Following example removes the noice from an image using the ImageFilter.MedianFilter().

    main.py

    from PIL import Image, ImageFilter
    
    # Open an image
    input_image = Image.open("Images/balloons_noisy.jpg")
    
    # Apply median filter with a kernel size 
    filtered_image = input_image.filter(ImageFilter.MedianFilter(size=3))
    
    # Display the input and the filtered image
    input_image.show()
    filtered_image.show()
    

    Input Noisy Image

    balloons noisy

    Output Median Filtered Image

    filtered image balloons

    Exampl - Reducing Noise in Grayscale Image

    This example demonstrates the reduction of salt-and-pepper noise in a grayscale image. This can be done by using a median filter, enhancing the contrast to improve visibility, and subsequently converting the image to binary mode for display.

    main.py

    from PIL import Image, ImageEnhance, ImageFilter, ImageOps
    
    # Open the image and convert it to grayscale
    input_image = ImageOps.grayscale(Image.open('Images/salt-and-pepper_noise.jpg'))
    
    # Apply a median filter with a kernel size of 5 to reduce noise
    filtered_image = input_image.filter(ImageFilter.MedianFilter(5))
    
    # Enhance the contrast of the filtered image
    contrast_enhancer = ImageEnhance.Contrast(filtered_image)
    high_contrast_image = contrast_enhancer.enhance(3)
    
    # Convert the image to binary
    binary_image = high_contrast_image.convert('1')
    
    # Display the input and processed images
    input_image.show()
    binary_image.show()
    

    Input Noisy Image

    salt and pepper noise

    Output Median Filtered Image

    median filtered

    Python Pillow - Extracting Image Metadata



    Image metadata refers to information associated with a digital image. This metadata can include various details, such as camera model, date and time of capture, location information (GPS coordinates), and keywords.

    In this context, extracting image metadata retrieves this underlying information from an image. One widely used type of image metadata is EXIF data, short for "Exchangeable Image File Format." This standardized format, established by organizations like Canon, Minolta/Sony, and Nikon, encapsulates a comprehensive set of specifics related to the image, including camera settings, exposure parameters, and more.

    It's important to note that all EXIF data is metadata, but not all metadata is EXIF data. EXIF is a specific type of metadata, and the data you're seeking might also fall under other metadata types, such as IPTC or XMP data.

    Example - Extracting Basic Image Metadata

    The Python Pillow Image object offers a straightforward way of accessing the basic image metadata, including the filename, dimensions, format, mode, and more.

    The example demonstrates how to extract various basic metadata from an image using attributes of the Pillow Image object.

    main.py

    from PIL import Image
    
    # Path to the image
    image_path = "Images/dance-cartoon.gif"
    
    # Read the image data using Pillow
    image = Image.open(image_path)
    
    # Access and print basic image metadata
    print("Filename:", image.filename)
    print("Image Size:", image.size)
    print("Image Height:", image.height)
    print("Image Width:", image.width)
    print("Image Format:", image.format)
    print("Image Mode:", image.mode)
    
    # Check if the image is animated (for GIF images)
    if hasattr(image, "is_animated"):
       print("Image is Animated:", image.is_animated)
       print("Frames in Image:", image.n_frames)
    

    Output

    Filename: Images/dance-cartoon.gif
    Image Size: (370, 300)
    Image Height: 300
    Image Width: 370
    Image Format: GIF
    Image Mode: P
    Image is Animated: True
    Frames in Image: 12
    

    Extracting Advanced Image Metadata

    The Python Pillow library offers tools to access and manage image metadata, specifically through the Image.getexif() function and the ExifTags module.

    The Image.getexif() function retrieves EXIF data from an image, which includes a wealth of valuable information about the image. The syntax for using this function is −

    Image.getexif()
    

    The function returns an Exif object, This object provides read and write access to EXIF image data.

    The PIL.ExifTags.TAGS dictionary is used to interpret EXIF data. This dictionary maps 16-bit integer EXIF tag enumerations to human-readable descriptive string names, making the metadata easier to understand. The syntax for this dictionary is −

    PIL.ExifTags.TAGS: dict
    

    Example - Getting EXIF metadata

    The following example demonstrates how to access and print EXIF metadata from an image file using Pillow's getexif() method. It also shows how to use the TAGS dictionary to map tag IDs to human-readable tag names.

    main.py

    from PIL import Image
    from PIL.ExifTags import TAGS
    
    # The path to the image 
    image_path = "Images/flowers_canon.JPG"
    
    # Open the image using the PIL library
    image = Image.open(image_path)
    
    # Extract EXIF data
    exif_data = image.getexif()
    
    # Iterate over all EXIF data fields
    for tag_id, data in exif_data.items():
        
       # Get the tag name, instead of the tag ID
       tag_name = TAGS.get(tag_id, tag_id)
       print(f"{tag_name:25}: {data}")
    

    Output

    GPSInfo                  : 10628
    ResolutionUnit           : 2
    ExifOffset               : 360
    Make                     : Canon
    Model                    : Canon EOS 80D
    YResolution              : 72.0
    Orientation              : 8
    DateTime                 : 2020:10:25 15:39:08
    YCbCrPositioning         : 2
    Copyright                : CAMERAMAN_SAI
    XResolution              : 72.0
    Artist                   : CAMERAMAN_SAI
    

    Python Pillow - Identifying Colors



    In the context of image processing and analysis, identifying colors refers to the process of recognizing, categorizing, and extracting information about the different Colors on an Image. It involves the analysis of pixel data to determine the specific colors or color patterns within the image.

    The Python Pillow library offers valuable tools for this purpose. This tutorial explores two fundamental functions, namely, getcolors() and getdata(), which play a crucial role in efficiently analyzing the color information present within images.

    Identifying Colors with the getcolors() function

    The getcolors() function returns a list of colors used within the image, with the colors represented in the image's mode. For example, in an RGB image, the function returns a tuple containing red, green, and blue color values. For a palette-based (P) image, it returns the index of the color in the palette. The syntax for using this function is −

    Image.getcolors(maxcolors=256)
    

    Where, maxcolors parameter is used to specify the maximum number of colors to retrieve. And it returns an unsorted list of tuples, each containing a count of occurrences and the corresponding color pixel value. If this maxcolors limit is exceeded, the method returns None (default limit: 256 colors).

    Example - Extracting Colors from an Image

    This example identifies the most frequent colors in an image using the Image.getcolors() function. It extracts the top 10 most common colors from the image and creates a color palette to visualize and display these colors along with their respective counts.

    main.py

    from PIL import Image, ImageDraw
    
    # Open an image
    input_image = Image.open('Images/colorful_shapes.jpg')
    
    # Get the palette of the top 10 most common colors
    palette = sorted(input_image.getcolors(maxcolors=100000), reverse=True)[:10]
    
    cols = 2
    rows = ((len(palette) - 1) // cols) + 1
    cellHeight = 70
    cellWidth = 200
    imgHeight = cellHeight * rows
    imgWidth = cellWidth * cols
    
    result_image = Image.new("RGB", (imgWidth, imgHeight), (0, 0, 0))
    draw = ImageDraw.Draw(result_image)
    
    for idx, (count, color) in enumerate(palette):
       y0 = cellHeight * (idx // cols)
       y1 = y0 + cellHeight
       x0 = cellWidth * (idx % cols)
       x1 = x0 + (cellWidth // 4)
       
       draw.rectangle([x0, y0, x1, y1], fill=color, outline='black')
       draw.text((x1 + 1, y0 + 10), f"Count: {count}", fill='white')
    
    # Display the input image
    input_image.show('Input Image')
    
    # Display the color chart
    result_image.show('Output identified Colors')
    

    Input Image

    colorful shapes

    Output identified Colors

    color chart
    It is important to note that the getcolors() function returns None when the number of colors in the image is greater than the maxcolors argument. And it primarily works with 'RGB' images, which may not be ideal for all use cases.

    For scenarios where you need more flexibility or when working with images of different color modes, using the Image.getdata() function in combination with other Python libraries can be a more convenient

    Identifying Colors with the getdata() function

    The getdata() function is another function within Pillow Image module that allows users to access the contents of an image as a sequence object containing pixel values. The sequence object is flattened, meaning values for each line follow directly after the values of the zero line, and so on. While the sequence object returned by this method is an internal Pillow data type, it can only support certain sequence operations, such as a Python list, for more convenient manipulation and printing. Here is the syntax of the function −

    Image.getdata(band=None)
    

    The parameters band is used to specify the band to return (default: all bands). To retrieve a single band, provide the index value (e.g., 0 to obtain the "R" band from an "RGB" image). And the function returns a sequence-like object that can be converted into more familiar data structures for further processing.

    Example - Counting Colors of an Image

    Here is an example that identifies the colors in an image and counts the occurrences of each color using the Image.getdata() function.

    main.py

    from PIL import Image
    from collections import defaultdict
    
    # Open an imagefrom PIL import Image
    from collections import defaultdict
    
    # Open an image
    im = Image.open('Images/sea1.jpg')
    
    # Create a defaultdict to store color counts
    colors = defaultdict(int)
    
    # Iterate through the image pixels and count each color
    for pixel in im.getdata():
        colors[pixel] += 1
    
    # Sort the colors by count in descending order
    ordered_colors = sorted(colors.items(), key=lambda x: x[1], reverse=True)
    
    # Print the top 10 colors and their counts
    for color, count in ordered_colors[:10]:
        print(f"Color: {color}, Count: {count}")
    from PIL import Image
    from collections import defaultdict
    
    # Open an image
    im = Image.open('Images/sea1.jpg')
    
    # Create a defaultdict to store color counts
    colors = defaultdict(int)
    
    # Iterate through the image pixels and count each color
    for pixel in im.getdata():
        colors[pixel] += 1
    
    # Sort the colors by count in descending order
    ordered_colors = sorted(colors.items(), key=lambda x: x[1], reverse=True)
    # Print the top 10 colors and their counts
    for color, count in ordered_colors[:10]:
        print(f"Color: {color}, Count: {count}")
    
    im = Image.open('Images/sea1.jpg')
    
    # Create a defaultdict to store color counts
    colors = defaultdict(int)
    
    # Iterate through the image pixels and count each color
    for pixel in im.getdata():
       colors[pixel] += 1
    
    # Sort the colors by count in descending order
    ordered_colors = sorted(colors.items(), key=lambda x: x[1], reverse=True)
    
    # Print the top 10 colors and their counts
    for color, count in ordered_colors[:10]:
       print(f"Color: {color}, Count: {count}")
    

    Output

    Color: (255, 255, 255), Count: 82
    Color: (0, 33, 68), Count: 73
    Color: (0, 74, 139), Count: 71
    Color: (0, 78, 144), Count: 69
    Color: (0, 77, 143), Count: 62
    Color: (0, 63, 107), Count: 59
    Color: (0, 34, 72), Count: 56
    Color: (0, 36, 72), Count: 52
    Color: (0, 30, 58), Count: 51
    Color: (1, 26, 56), Count: 51
    

    Example - Counting Most Frequent Color

    The following example identifies the most frequent color in an image and counts the occurrences of the color using the Image.getdata() function together with Python collections library.

    main.py

    from PIL import Image
    from collections import Counter
    
    # Open an image
    image = Image.open('Images/Road.jpg')
    
    # Get a Counter dictionary of colors and their frequencies
    colors = Counter(image.getdata())
    
    # Get a set of unique colors
    unique_colors = set(colors)
    
    # Get the number of unique colors
    num_unique_colors = len(unique_colors)
    
    # Get the color with the highest frequency
    most_frequent_color = max(colors, key=colors.get)
    
    print(f"Unique Colors: {num_unique_colors}")
    print(f"Most Frequent Color: {most_frequent_color} with a frequency of {colors[most_frequent_color]}")
    

    Output

    Unique Colors: 18323
    Most Frequent Color: (26, 27, 31) with a frequency of 5598
    

    Python Pillow - Creating Animated GIFs



    The GIF (Graphics Interchange Format), is a bitmap image format developed by a team at CompuServe, an online services provider, under the leadership of American computer scientist Steve Wilhite. GIF ware not designed as an animation medium. However, its ability to store multiple images within a single file made it a logical choice for representing the frames of an animation sequence. To support the presentation of animations, the GIF89a specification introduced the Graphic Control Extension (GCE). This extension enables the specification of time delays for each frame, effectively allowing the creation of a video clip from a series of images.

    In an animated GIF, each frame is introduced by its own GCE, specifying the time delay that should occur after the frame is drawn. Additionally, global information defined at the beginning of the file applies as the default setting for all frames, simplifying the management of animation settings and behaviors.

    Python's Pillow library can read GIF files in both GIF87a and GIF89a formats. By default, it writes GIF files in GIF87a format unless GIF89a features are used or the input file is already in GIF89a format. The saved files use LZW encoding.

    Creating Animated GIFs with Python Pillow

    It is possible to create animated GIFs using Pillow's Image.save() function. Below are the syntax and the available options when calling save() function to save a GIF file −

    Syntax:

    Image.save(out, save_all=True, append_images=[im1, im2, ...])
    

    Options:

    • save_all − If set to true, it saves all frames of the image. Otherwise, it saves only the first frame of a multi-frame image.

    • append_images − This option allows appending a list of images as additional frames. The images in the list can be single or multi-frame images. This feature is supported for GIF, PDF, PNG, TIFF, and WebP formats, as well as for ICO and ICNS formats. When images of relevant sizes are provided, they will be used instead of scaling down the main image.

    • include_color_table − Determines whether or not to include a local color table.

    • interlace − Specifies whether the image is interlaced. By default, interlacing is enabled, unless the image's width or height is less than 16 pixels.

    • disposal − Indicates how the graphic should be treated after being displayed. It can be set to values like 0 (no disposal specified), 1 (do not dispose), 2 (restore to the background color), or 3 (restore to previous content). You can pass a single integer for a constant disposal or a list/tuple to set disposal for each frame separately.

    • palette − This option allows you to use a specified palette for the saved image. The palette should be provided as a bytes or bytearray object containing the palette entries in RGBRGB... form. It should be no more than 768 bytes. Alternatively, you can pass the palette as a PIL.ImagePalette.ImagePalette object.

    • optimize − If set to true, it attempts to compress the palette by eliminating unused colors. This optimization is useful when the palette can be compressed to the next smaller power of 2 elements.

    • Additional options like transparency, duration, loop, and comment can be provided to control specific aspects of the animated GIF.

    Example - Creating an Animated GIF image

    Here is an example that demonstrates how to create a GIF animation by generating individual frames with different colors and saving them.

    main.py

    import numpy as np
    from PIL import Image
    
    # Function to create a new image with a specified width, height, and color
    def create_image(width, height, color):
       return Image.new("RGBA", (width, height), color)
    
    # Set the width and height of the images
    width, height = 300, 300
    
    # Define the colors for the images
    colors = [(64, 64, 3), (255, 0, 0), (255, 255, 0), (255, 255, 255), (164, 0, 3)]
    
    # Create a list of images using a list comprehension
    images = [create_image(width, height, color) for color in colors]
    
    # Save the images as a GIF with specified parameters
    images[0].save("Output.gif", save_all=True, append_images=images[1:], duration=1000/2, loop=0)
    

    Output

    The animated GIFs file is saved successfully...
    

    Below you can see the saved animated GIFs in your working directory −

    color

    Example - Creating GIF using multiple Images

    The following example takes a list of existing image files to create an animated GIF by saving these images in sequence.

    main.py

    from PIL import Image
    
    # List of file paths for existing images
    image_paths = ['Images/book_1.jpg', 'Images/book_2.jpg', 'Images/book_3.jpg', 'Images/book_4.jpg']
    
    # Create a list of image objects from the provided file paths
    image_list = [Image.open(path) for path in image_paths]
    
    # Save the first image as an animated GIF
    output_path = \Book_Animation.gif'
    
    image_list[0].save(
       output_path,
       save_all=True,
       append_images=image_list[1:],  # Append the remaining images
       duration=1000,  # Frame duration in milliseconds
       loop=0
    )
    
    print('The animated GIF file has been created and saved successfully...')
    

    Output

    The animated GIF file has been created and saved successfully...
    

    The following image represents the saved animated GIFs in your working directory −

    book animation

    Example - Modifying an Existing GIF file

    This example modifies an existing GIF file by duplicating its last frame a few times and then saves it as a new GIF file. In this example we will use the ImageSequence module to iterate each frames from the input GIF file.

    main.py

    from PIL import Image, ImageSequence
    
    # Open the existing GIF file 
    input_image = Image.open("Book_Animation.gif")
    
    # Create an empty list to store the frames of the GIF
    frames = []
    
    # Iterate over the frames of the GIF and append them to the frames list
    for frame in ImageSequence.Iterator(input_image):
       frames.append(frame)
    
    # Duplicate the last frame three times to extend the animation
    for i in range(3):
       frames.append(frames[-1])
    
    # Save the frames as a new GIF file ("newGif.gif"):
    output_path = "newGif.gif"
    frames[0].save(
       output_path,
       save_all=True,
       append_images=frames[1:],
       optimize=False,
       duration=40,  # Set the frame duration to 40 milliseconds
       loop=0
    )
    

    Output

    The following image represents the saved animated GIFs in your working directory −

    book animation

    Python Pillow - Batch Processing of Images



    Batch processing images in Python Pillow allows you to efficiently apply the same edits or operations to multiple images simultaneously. This approach is valuable for tasks like resizing, cropping, renaming, watermarking, or formatting images, as it enhances workflow efficiency and optimizes output.

    This is particularly useful when working with a large number of images, as it can significantly impact the speed and efficiency of your computer. It allows you to apply the same operation to each image, saving time and effort.

    Steps for Batch Processing Images

    The steps involved in batch processing images with Python Pillow are as follows −

    • Create a List of Image Files: Generate a list of file paths to the images you want to process.

    • Iterate Through the List of Images: Use loops to traverse the list of image files. You can use 'for' or 'while' loops to handle each image one at a time.

    • Perform Image Processing Operations: Within the loop, apply the desired image processing operations to each image. This may include resizing, cropping, applying filters, adding text or watermarks, or any other operation necessary.

    • Save Processed Images: After performing the processing operations on each image, save the processed image to the desired location.

    Example - Resizing Images using Batch Processing

    Resizing images using Python Pillow batch processing is one of the common tasks in image processing. It involves adjusting the dimensions of multiple images to a specific size or aspect ratio.

    Here is an example that demonstrates the resizing multiple images at once using the Python Pillow batch processing. In this example, a collection of JPG images in a specified folder is resized to a specific size (e.g., 700x400).

    main.py

    from PIL import Image
    import glob
    import os
    
    # Get a list of image files in the 'Images' directory
    input_directory = "Images"
    output_directory = "Output_Images"
    
    image_files = [f for f in glob.glob(os.path.join(input_directory, "*.jpg"))]
    
    for file in image_files:
       image = Image.open(file)
       
       # Resize the image to a specific size (e.g., 700x400)
       image = image.resize((700, 400))
       
       # Save the resized image to the 'Output directory for Batch Operation' directory
       output_path = os.path.join(output_directory, os.path.basename(file))
       image.save(output_path)
    

    Output

    Following image represents the list of image files available in the input directory −

    list of image

    If we navigate to the directory where the output image was saved (i.e, "Output directory for Batch Operation"), we will be able to observe resized images as shown below −

    resized images

    Example - Renaming Images using the Batch Processing

    Renaming images is another frequently performed task in batch processing. It involves changing the filenames of multiple images according to a specified pattern.

    The following example adds the prefix "New_" to the names of a batch of PNG images located in the specified input_directory. It renames these images and saves them in the output_directory with the new names.

    main.py

    from PIL import Image
    import glob
    import os
    
    # Get a list of image files in the 'Images' directory
    input_directory = "Images"
    output_directory = "Output_Images"
    
    image_files = [f for f in glob.glob(os.path.join(input_directory, "*.png"))]
    
    for file in image_files:
       image = Image.open(file)
       
       # Save the image with the new name to the 'Output directory for Batch Operation' directory
       output_path = os.path.join(output_directory, 'New_'+os.path.basename(file))
       image.save(output_path)
    

    Output

    Following image represents the list of image files available in the input directory −

    image files

    If we navigate to the directory where the output image was saved (i.e, "Output directory for Batch Operation"), we will be able to observe renamed images as shown below −

    output directory

    Python Pillow - Converting Image Formats



    Converting image file formats with Python Pillow is a straightforward process. You can open an image in one format and save it in another, specifying the desired output format. This process typically involves the following steps −

    • Open the Source Image: Use the Image.open() function to open the source image.

    • Save the Image: Use the save() method to save the image in the desired format, specifying the new file format and destination.

    Pillow can recognize and read over 30 different formats. When using the open() function, Pillow determines the format based on the image content, not just the file name. However, when saving images with the save() method, it usually looks at the file name to decide the format unless you specifically tell which format to use.

    Pillow Supported File Formats

    Pillow supports various image formats for both reading and writing. Some formats are fully supported, meaning you can both read from and write to images in those formats. These include popular formats like JPEG, PNG, BMP, BLP, DDS, EPS, GIF, ICNS, ICO, MSP, PCX, PNG, PPM, SGI, TGA, TIFF, WebP, and XBM.

    Additionally, it provides read-only and write-only support for a range of other formats.

    • Read-Only Formats: CUR, DCX, FITS, FLI, FLC, FPX, GBR, GD, IMT, IPTC/NAA, MCIDAS, MIC, MPO, PCD, PIXAR, PSD, QOI, SUN, WAL, and WMF/EMF.
    • Write-Only Formats: PALM, PDF, and XV Thumbnails.

    The library can also identify the format of images in formats such as BUFR, GRIB, HDF5, and MPEG. Let's see the exmaples of converting image file formats with Python Pillow.

    Example - Converting JPG to PNG Format

    This example converts the image from JPEG to PNG format.

    main.py

    from PIL import Image
    
    # Open the source image in JPEG format
    image = Image.open("Images/logo.jpg")
    
    # Convert and save the image in PNG format
    image.save("output_image_PNG_format.png")
    print("Image saved successfully in PNG format...")
    

    Output

    Image saved successfully in PNG format...
    

    Example - Converting BMP to GIF Format

    This example converts the image from BMP to GIF format.

    main.py

    from PIL import Image
    
    # Open the source image in BMP format
    image = Image.open("Images/lena.bmp")
    
    # Convert and save the image in GIF format
    image.save("output_image.gif")
    print("Image saved successfully in GIF format...")
    

    Output

    Image saved successfully in GIF format...
    

    Example - Converting GIF to TIFF Format

    This example converts the image from GIF to TIFF format.

    main.py

    from PIL import Image
    
    # Open the source image in GIF format
    image = Image.open("Images/Book_Animation.gif")
    
    # Convert and save the image in TIFF format
    image.save("output_image.tiff")
    print("Image saved successfully in TIFF format...")
    

    Output

    Image saved successfully in TIFF format...
    

    Example - Converting BPM to JPG Format

    This example converts the image from .bpm file format to .jpg format.

    main.py

    from PIL import Image
    
    # Open the source image in BMP format
    image = Image.open("Images/lena.bmp")
    
    # Convert and save the image in JPEG format
    image.save('lena_new.jpg')
    print("Image saved successfully in JPEG format...")
    

    Output

    Image saved successfully in JPEG format...
    

    If you visit the folder where the output images are saved you can observe resultant images.

    Python Pillow - Adding Padding to Image



    Adding padding to an image involves adding a border around it. This is a useful technique while adjusting the image's size without changing its aspect ratio or trimming it. Padding can be added to the top, bottom, left, and right sides of the image. This is particularly important when working with images that have important information at the edges, which you want to retain for tasks like segmentation.

    The Pillow (PIL) library provides two functions, pad() and expand(), within its ImageOps module for adding padding to images.

    Padding Images with ImageOps.pad() function

    The pad() function is used to resize and pad an image to a specified size and aspect ratio. It allows you to specify the output size, resampling method, background color, and positioning of the original image within the padded area. Syntax of this function as follows −

    PIL.ImageOps.pad(image, size, method=Resampling.BICUBIC, color=None, centering=(0.5, 0.5))
    

    Where,

    • image − The image to resize and pad.

    • size − A tuple specifying the requested output size in pixels, in the format (width, height). The function will resize the image to this size while maintaining the aspect ratio.

    • method − This parameter determines the resampling method used during resizing. The default method is BICUBIC, which is a type of interpolation. You can specify other resampling methods supported by PIL. Common options include NEAREST, BILINEAR, and LANCZOS.

    • color − This parameter specifies the background color of the padded area. It supports the RGBA tuple also, like (R, G, B, A). If not specified, the default background color is black.

    • centering − This parameter controls the position of the original image within the padded version. It's specified as a tuple with two values between 0 and 1.

    Example - Adding Padding To an Image

    Here is an example that adds padding to an image using the ImageOps.pad() function.

    main.py

    from PIL import Image
    from PIL import ImageOps
    
    # Open the input image
    input_image = Image.open('Images/elephant.jpg')
    
    # Add padding to the image
    image_with_padding = ImageOps.pad(input_image, (700, 300), color=(130, 200, 230))
    
    # Display the input image
    input_image.show()
    
    # Display the image with the padding
    image_with_padding.show()
    

    Input Image

    elephant

    Output Image

    Output image After resizing with padding −

    elephant resize

    Adding Borders with the ImageOps.expand() function

    The expand() function adds a border of a specified width and color around the image. It is useful for creating a decorative frame or emphasizing the content of the image. Its syntax is as follows −

    PIL.ImageOps.expand(image, border=0, fill=0)
    
    • image − The image to expand the border.

    • border − The width of the border to add, specified in pixels. It determines how wide the border will be around the image. The default value is (0).

    • fill − The pixel fill value, which represents the color of the border. The default value is 0, which corresponds to black. You can specify the fill color using an appropriate color value.

    Example - Adding Borders to an Image

    Here is an example that adds padding to an image using the ImageOps.expand() function.

    main.py

    from PIL import Image, ImageOps
    
    # Open the input image
    input_image = Image.open('Images/yellow_car.jpg')
    
    # Add padding of 15-pixel border
    image_with_padding = ImageOps.expand(input_image, border=(15, 15, 15, 15), fill=(255, 180, 0))
    
    # Display the input image
    input_image.show()
    
    # Display the output image with padding
    image_with_padding.show()
    

    Input Image

    yellow car

    Output Image

    Output image with padding −

    car border

    Python Pillow - Color Inversion



    Color inversion in Python Pillow is a popular photo effect, that transforms an image by reversing the colors to their complementary hues on the color wheel. It results in changes such as black becoming white, white becoming black, and other color shifts.

    This technique, also referred to as image inversion or color negation, is a method in image processing that systematically alters the colors within an image. In a color-inverted image, the colors are transformed in such a way that light areas become dark, dark areas become light, and colors are inverted across the color spectrum.

    Applying the Color Inversion to an Image

    In Python Pillow, color inversion is achieved through the inversion of colors across the image spectrum. The library offers the invert() function within its ImageOps module, allowing you to apply color inversion to the images. This function is designed to negate the colors of a given image, effectively applying the color inversion effect. The syntax of the method is as follows −

    PIL.ImageOps.invert(image)
    

    Where,

    • image − This is the input image to invert.

    Example - Getting an Inverted Image

    The following example creates an inverted version of an input image using the PIL.ImageOps.invert() function.

    main.py

    from PIL import Image
    import PIL.ImageOps
    
    # Open an image
    input_image = Image.open('Images/butterfly.jpg')
    
    # Create an inverted version of the image
    inverted_image = PIL.ImageOps.invert(input_image)
    
    # Display the input image
    input_image.show()
    
    # Display the inverted image
    inverted_image.show()
    

    Input Image

    butterfly and flowers

    Output inverted image

    butterfly inverted image

    Example - Applying the Color Inversion to RGBA Images

    While most functions in the ImageOps module are designed to work with L (grayscale) and RGB images. When you attempt to apply this invert function to an image with RGBA mode (which includes an alpha channel for transparency), it will indeed raise an OSError stating that it is not supported for that image mode.

    Here is an example that demonstrates how to work with RGBA images while handling transparency.

    main.py

    from PIL import Image
    import PIL.ImageOps
    
    # Open an image
    input_image = Image.open('Images/python_logo_input.jpg')
    
    # Display the input image
    input_image.show()
    
    # Check if the image has an RGBA mode
    if input_image.mode == 'RGBA':
        
       # Split the RGBA image into its components
       r, g, b, a = input_image.split()
       
       # Create an RGB image by merging the red, green, and blue components
       rgb_image = Image.merge('RGB', (r, g, b))
       
       # Invert the RGB image
       inverted_image = PIL.ImageOps.invert(rgb_image)
       
       # Split the inverted image into its components
       r2, g2, b2 = inverted_image.split()
       
       # Merge the inverted RGB image with the original alpha channel to maintain transparency
       final_transparent_image = Image.merge('RGBA', (r2, g2, b2, a))
       
       # Show the final transparent image
       final_transparent_image.show()
    else:
       # Invert the image for non-RGBA images
       inverted_image = PIL.ImageOps.invert(input_image)
       inverted_image.show()
    

    Input Image

    python logo

    Output inverted image

    inverted python logo

    Python Pillow - M L with Numpy



    Image manipulation with NumPy is a common practice in image processing tasks. NumPy provides a powerful array manipulation library that complements Pillow's image processing capabilities. This tutorial demonstrates how to use Pillow with NumPy for efficient image processing.

    Installation

    Before proceeding, ensure we have NumPy installed. Open the command prompt in administrator mode and execute the following command −

    pip install numpy
    

    Note − This command works only if you have PIP installed and updated.

    Creating image from Numpy Array

    When working with NumPy arrays as images, we can use the Image.fromarray() function to create an image memory from an object that exports the array interface, typically using the buffer protocol. If the input array (obj) is contiguous in memory, Pillow can use the array interface directly. If the array is not contiguous, Pillow will use the tobytes method, and frombuffer() will be used to create the image. Here's the syntax of the fromarray() function −

    PIL.Image.fromarray(obj, mode=None)
    

    Where,

    • obj − The object exporting the array interface. This is usually a NumPy array, but it can be any object that exposes the required interface.

    • mode (optional) − The mode parameter specifies the color mode or pixel format of the resulting image. If not provided, the mode is inferred from the type of the input array.

    It's important to note that Pillow modes (color modes) do not always correspond directly to NumPy data types (dtypes). Pillow modes include options for 1-bit pixels, 8-bit pixels, 32-bit signed integer pixels, and 32-bit floating-point pixels. The mode is either explicitly specified or inferred from the dtype of the input array.

    Example - Creating Image using NumPy Array

    In this example, a NumPy array is created, and then Image.fromarray() is used to create a Pillow Image from the NumPy array. The resulting image is a Pillow Image object that can be further processed or saved.

    main.py

    from PIL import Image
    import numpy as np
    
    # Create a NumPy array
    arr = np.zeros([150, 250, 3], dtype=np.uint8)
    arr[:,:100] = [255, 128, 0]
    arr[:,100:] = [0, 0, 255]
    
    # Create a Pillow Image from the NumPy array
    image = Image.fromarray(arr)
    
    # Display the created image
    image.show()
    

    Output

    created image

    Example - Creating Image with Mode

    Here is another example that create a Pillow Image from the NumPy array by explicitly specifying the mode.

    main.py

    from PIL import Image
    import numpy as np
    
    # Create a NumPy array
    arr = np.zeros([250, 350, 3], dtype=np.uint8)
    arr[:100, :200] = 250
    
    # Create a Pillow Image from the NumPy array by explicitly specifying the mode
    image = Image.fromarray(arr, mode='RGB')
    
    # Display the created image
    image.show()
    

    Output

    created image black and white

    Example - Creating a Grayscale

    This example creates a grayscale image from a numpy 2-dimensional array by explicitly specifying the mode equal to "L".

    main.py

    from PIL import Image
    import numpy as np
    
    # Create a NumPy array
    arr = np.zeros([300, 700], dtype=np.uint8)
    arr[100:200, 100:600] = 250
    
    # Create a Pillow grayscale Image from the NumPy array 
    # by explicitly specifying the mode
    image = Image.fromarray(arr, mode='L')
    print("Pixel values of image at (150, 150) of the grayscale image is:", image.getpixel((150, 150)))
    
    # Display the created image
    image.show()
    

    Output

    Pixel values of image at (150, 150) of the grayscale image is: 250
    
    grayscale image

    Example - Creating numpy array from a Pillow Image

    The numpy.asarray() function can be used to convert a Pillow image to a NumPy array. However, it's important to note that when converting Pillow images to arrays, only the pixel values are transferred. This means that certain image modes, like P and PA, will lose their palette information during the conversion.

    The following example demonstrates how to convert a Pillow image to a NumPy array.

    main.py

    from PIL import Image
    import numpy as np
    
    # Open an image as a pillow image object
    image = Image.open("Images/tutorialspoint.jpg")
    
    # Convert the Pillow image to a NumPy array
    result = np.asarray(image)
    
    # Display the type, shape and dtype of the NumPy array
    print("Type:", type(result))
    print("Shape:", result.shape)
    print("Dtype:", result.dtype)
    

    Output

    Type: <class 'numpy.ndarray'>
    Shape: (225, 225, 3)
    Dtype: uint8
    

    Python Pillow with Tkinter BitmapImage and PhotoImage objects



    The ImageTk module in the python pillow library provides functionality to create and manipulate Tkinter BitmapImage and PhotoImage objects from PIL images. This tutorial discusses the descriptions of the key classes and methods within the ImageTk module.

    These classes and methods provide convenient ways to work with Tkinter images using PIL in Python, allowing for integration of images into graphical user interfaces.

    Tkinter BitmapImage class in Python Pillow

    The ImageTk.BitmapImage class represents a Tkinter-compatible bitmap image that can be utilized wherever Tkinter expects an image object.

    Here are the key details about the class −

    • The provided image must have a mode of "1".

    • Pixels with a value of 0 are considered transparent.

    • Additional options, if provided, are forwarded to Tkinter.

    • A commonly used option is foreground, allowing specification of the color for non-transparent parts.

    Following is the syntax of the ImageTk.BitmapImage() class −

    class PIL.ImageTk.BitmapImage(image=None, **kw)
    

    Where,

    • image − A PIL image with mode "1". Pixels with value 0 are treated as transparent.

    • **kw − Additional options passed on to Tkinter. The most commonly used option is foreground, which specifies the color for the non-transparent parts.

    Following are the list of methods provided by the BitmapImage class −

    • height() − Returns the height of the image in pixels.

    • width() − Returns the width of the image in pixels.

    Example - Creating Image in Tkinter Window

    Here is an example demonstrating creating Tkinter windows, loading images with PIL, and then using ImageTk.BitmapImage to create Tkinter-compatible image objects for display in a Tkinter Label.

    main.py

    from tkinter import *
    from PIL import ImageTk, Image
    
    # Create a Tkinter window
    root = Tk()
    
    # Create a sample image 1-bit mode image (black and white)
    pil_image = Image.new("1", (700, 300), color=1)  
     
    # Create a BitmapImage from the PIL image
    bitmap_image = ImageTk.BitmapImage(pil_image, background='', foreground='gray')
    
    # Display the BitmapImage in a Tkinter Label
    label = Label(root, image=bitmap_image)
    label.pack()
    
    # Run the Tkinter event loop
    root.mainloop()
    

    Output

    tk bitmapimage

    The PhotoImage class in Python Pillow

    The ImageTk.PhotoImage() class represents a Tkinter-compatible photo image in Pillow, it suitable for use wherever Tkinter expects an image object.

    Here are the key details about the class −

    • If the image is in RGBA format, pixels with an alpha value of 0 are treated as transparent.

    • The constructor can be initialized with either a PIL image, or a mode and size. Alternatively, you have the option to use the file or data parameters to initialize the photo image object.

    Here is the syntax of the ImageTk.PhotoImage() class −

    class PIL.ImageTk.PhotoImage(image=None, size=None, **kw)
    

    Where,

    • image − Represents either a PIL image or a mode string. If a mode string is used, a size must also be given.

    • size − If the first argument is a mode string, this defines the size of the image.

    • file − A filename to load the image from using Image.open(file).

    • data − An 8-bit string containing image data, as loaded from an image file.

    Following are the list of methods provided by the PhotoImage() class −

    • height() − Get the height of the image in pixels.

    • width() − Get the width of the image in pixels.

    • paste(im) − Paste a PIL image into the photo image. Note that this can be slow if the photo image is displayed.

    • Parameters − im - A PIL image. The size must match the target region. If the mode does not match, the image is converted to the mode of the bitmap image.

    Example - Loading Image in Tkinter Window

    Here is an example demonstrating creating Tkinter windows, loading images with PIL, and then using ImageTk.PhotoImage to create Tkinter-compatible image objects for display in a Tkinter Label.

    main.py

    from tkinter import *
    from PIL import ImageTk, Image
    
    # Create a Tkinter window
    root = Tk()
    
    # Create a canvas widget
    canvas = Canvas(root, width=700, height=400, bg='white')
    canvas.grid(row=2, column=3)
    
    # Load an image using PIL and create a PhotoImage
    pil_image = Image.open("Images/pillow_logo_w.jpg")
    tk_image = ImageTk.PhotoImage(pil_image)
    
    # Draw the image on the canvas
    canvas.create_image(20, 20, anchor=NW, image=tk_image)
    
    # Start the Tkinter event loop
    mainloop()
    

    Output

    pillow logo w

    Python Pillow - Image Blending



    Image blending is a process of combining or mixing two images to create a new image. One common method for image blending is to use alpha blending. In alpha blending, each pixel in the result is computed based on a weighted sum of the corresponding pixels in the input images. The alpha channel, representing transparency, is used as the weight factor.

    This technique is commonly used in graphics, image processing, and computer vision to achieve various visual effects.

    The Python Pillow library provides the blend() function within its Image module to perform the blending operation on images.

    The Image.blend() function

    This function provides a convenient way to create a smooth transition between two images by specifying a blending factor (alpha). The function creates a new image by interpolating between two input images using a constant alpha value. The interpolation is performed according to the formula −

    out=image1×(1.0alpha)+image2×alpha
    

    Following is the syntax of the function −

    PIL.Image.blend(im1, im2, alpha)
    

    Where −

    • im1 − The first image.

    • im2 − The second image. It must have the same mode and size as the first image.

    • alpha − The interpolation alpha factor. If alpha is 0.0, a copy of the first image is returned. If alpha is 1.0, a copy of the second image is returned. There are no restrictions on the alpha value. If necessary, the result is clipped to fit into the allowed output range.

    Example - Blending Images

    Let's see a basic example of blending two images using the Image.blend() method.

    main.py

    from PIL import Image
    
    # Load two images
    image1 = Image.open("Images/ColorDots.png")
    image2 = Image.open("Images/pillow-logo-w.png")
    
    # Blend the images with alpha = 0.5
    result = Image.blend(image1, image2, alpha=0.5)
    
    # Display the input and resultant iamges
    image1.show()
    image2.show()
    result.show()
    

    Input Images

    color dots pillow logo

    Output

    resultant images

    Example - Blending Images with alpha as 2

    Here is an example that demonstrates the use of PIL.Image.blend() with alpha values 2.

    main.py

    from PIL import Image
    
    # Load two images
    image1 = Image.open("Images/ColorDots.png")
    image2 = Image.open("Images/pillow-logo-w.png")
    
    # Blend the images with alpha = 2
    result = Image.blend(image1, image2, alpha=2)
    
    # Display the input and resultant iamges
    image1.show()
    image2.show()
    result.show()
    

    Input Images

    color dots pillow logo

    Output

    image blend

    Example - Blending Images with alpha as 1

    Here is an example that demonstrates the use of PIL.Image.blend() with alpha value 1.0. It will return a copy of the second image.

    main.py

    from PIL import Image
    
    # Load two images
    image1 = Image.open("Images/ColorDots.png")
    image2 = Image.open("Images/pillow-logo-w.png")
    
    # Blend the images with alpha = 2
    result = Image.blend(image1, image2, alpha=1.0)
    
    # Display the input and resultant iamges
    image1.show()
    image2.show()
    result.show()
    

    Input Images

    color dots pillow logo

    Output

    pillow logo
    Advertisements