Create Feature Image With Python (Pillow)

This post is part of the complete Guide on Python for SEO

Creating Images for your blog can be a painful process.

I hate working on images, so I decided to always use the same background image template and create images automatically from a specific text in Python.

Actually, the feature image used for this post was created using the code that I am showing you here.

Join the Newsletter

    We will learn how to generate images in Python using the Pillow library. You can get the full code at the end of this post.

    How to Generate Images with Python

    To run this code, you will need to:

    • Install Python
    • Find a template background image

    You can read how to install Python with Anaconda.

    Step 1. Install the Pillow Library

    To do this Python image programming tutorial, we will use Pillow. Go to your Terminal and install the package.

    $ pip install Pillow
    

    You will load the PIL Image, ImageDraw and ImageFont modules.

    from PIL import Image, ImageDraw, ImageFont
    

    Step 2. Add the Features of Your Image

    Here we will have two text lines in order to give different styling to each line.

    # create Image object
    text1 = 'Create Feature Image'
    text2 = 'With Python'
    

    We will give the image output file a name.

    img_name = 'featured-image-creation-with-python.png'
    

    And choose which color we want to use as a filter of the image.

    color = 'dark_blue' #grey,light_blue,blue,orange,purple,yellow,green
    

    Then we will need to download the Roboto font from Github and add it to your work folder.

    font = 'Roboto-Bold.ttf'
    

    Step 3. Find Your Background Image

    If you want to find free images to use as background you can download one from Unsplash.

    In my case, I have used a very simple one that I will always use as a background image.

    Since I am frequently blogging about Python, I also found a Python logo to incorporate in my designs.

    Add images that you want in your work folder.

    In the code, you will see these lines that are my background image and the Python logo.

    background = Image.open('background.jpg')
    foreground = Image.open('python-logo.png')
    

    Step 4. Create The Color Templates

    Here I will create a dictionary to define background and text colour depending of the style that was chosen.

    colors = {
        'dark_blue':{'c':(27,53,81),'p_font':'rgb(255,255,255)','s_font':'rgb(255, 212, 55)'},
        'grey':{'c':(70,86,95),'p_font':'rgb(255,255,255)','s_font':'rgb(93,188,210)'},
        'light_blue':{'c':(93,188,210),'p_font':'rgb(27,53,81)','s_font':'rgb(255,255,255)'},
        'blue':{'c':(23,114,237),'p_font':'rgb(255,255,255)','s_font':'rgb(255, 255, 255)'},
        'orange':{'c':(242,174,100),'p_font':'rgb(0,0,0)','s_font':'rgb(0,0,0)'},
        'purple':{'c':(114,88,136),'p_font':'rgb(255,255,255)','s_font':'rgb(255, 212, 55)'},
        'red':{'c':(255,0,0),'p_font':'rgb(0,0,0)','s_font':'rgb(0,0,0)'},
        'yellow':{'c':(255,255,0),'p_font':'rgb(0,0,0)','s_font':'rgb(27,53,81)'},
        'yellow_green':{'c':(232,240,165),'p_font':'rgb(0,0,0)','s_font':'rgb(0,0,0)'},
        'green':{'c':(65, 162, 77),'p_font':'rgb(217, 210, 192)','s_font':'rgb(0, 0, 0)'}
        }
    

    Step 5. Define The Functions

    We will define a few functions.

    1. add_color() to add a coloured filter to the background image.
    2. center_text() to center the text in the image if there is no logo in the image.
    3. add_text() to actually add the text where we want it to be.
    4. add_logo() to add the logo when you have one, like in my case.
    5. write_image() to combine all the work and return the new image.

    Add Colour to the Image

    Here the function lets you define which image to take as the background image, the color (c), and the transparency level from 0 to 255.

    def add_color(image,c,transparency):
        color = Image.new('RGB',image.size,c)
        mask = Image.new('RGBA',image.size,(0,0,0,transparency))
        return Image.composite(image,color,mask).convert('RGB')
    

    Center Text

    This function will check the background image and the text size, an make calculation to make sure that the text will be center-aligned.

    def center_text(img,font,text1,text2,fill1,fill2):
        draw = ImageDraw.Draw(img) # Initialize drawing on the image
        w,h = img.size # get width and height of image
        t1_width, t1_height = draw.textsize(text1, font) # Get text1 size
        t2_width, t2_height = draw.textsize(text2, font) # Get text2 size
        p1 = ((w-t1_width)/2,h // 3) # H-center align text1
        p2 = ((w-t2_width)/2,h // 3 + h // 5) # H-center align text2
        draw.text(p1, text1, fill=fill1, font=font) # draw text on top of image
        draw.text(p2, text2, fill=fill2, font=font) # draw text on top of image
        return img
    

    Add Text to the Image

    This function will add text on the image.

    The font and font_size arguments are defined by default. Also, by default, the image will not have any additional images on top of it. It will simply be text over background.

    If you define a foreground image in the write_image() function that we will see later, the logo will be set to True, and the layout will change automatically.

    This is where the center_text() function comes in. If there is no logo set up, the image will return a centre-aligned text.

    def add_text(img,color,text1,text2,logo=False,font='Roboto-Bold.ttf',font_size=75):
        draw = ImageDraw.Draw(img)
    
        p_font = color['p_font']
        s_font = color['s_font']
        
        # starting position of the message
        img_w, img_h = img.size
        height = img_h // 3
        font = ImageFont.truetype(font,size=font_size)
    
        if logo == False:
            center_text(img,font,text1,text2,p_font,s_font)
        else:
            text1_offset = (img_w // 4, height)
            text2_offset = (img_w // 4, height + img_h // 5)
            draw.text(text1_offset, text1, fill=p_font, font=font)
            draw.text(text2_offset, text2, fill=s_font, font=font)
        return img
    

    Add a Logo to the Image

    You can add the image you want, but this function will simply add the image that you defined in the foreground variable to the layout.

    def add_logo(background,foreground):
        bg_w, bg_h = background.size
        img_w, img_h = foreground.size
        img_offset = (20, (bg_h - img_h) // 2)
        background.paste(foreground, img_offset, foreground)
        return background
    
    

    Combine all Steps to Write the Image

    Now it is time to put all that together in a single function.

    This functions set’s up the background image and adds it the colour overlay.

    If there is a foreground image to add on top of the background, it adds it and modify the text layout.

    Otherwise, it will center-align the text on top of the background image.

    def write_image(background,color,text1,text2,foreground=''):
        background = add_color(background,color['c'],25)
        if not foreground:
            add_text(background,color,text1,text2)
        else:
            add_text(background,color,text1,text2,logo=True)
            add_logo(background,foreground)
        return background
    

    Step 6. Run the Function

    There we will run the write_image() function and save it using the save() function.

    The if __name__ == '__main__' simply tells the program to execute the function only when you are executing the script, not when importing the module.

    if __name__ == '__main__':
        background = write_image(background,colors[color],text1,text2,foreground=foreground)
        background.save(img_name) 
    

    Full Code

    from PIL import Image, ImageDraw, ImageFont
     
    # create Image object
    text1 = 'Create Feature Image'
    text2 = 'With Python'
    img_name = 'featured-image-creation-with-python.png'
    color = 'dark_blue' #grey,light_blue,blue,orange,purple,yellow,green
    font = 'Roboto-Bold.ttf'
    
    background = Image.open('default.jpg')
    foreground = Image.open('python-logo.png')
    
    #create the coloured overlays
    colors = {
        'dark_blue':{'c':(27,53,81),'p_font':'rgb(255,255,255)','s_font':'rgb(255, 212, 55)'},
        'grey':{'c':(70,86,95),'p_font':'rgb(255,255,255)','s_font':'rgb(93,188,210)'},
        'light_blue':{'c':(93,188,210),'p_font':'rgb(27,53,81)','s_font':'rgb(255,255,255)'},
        'blue':{'c':(23,114,237),'p_font':'rgb(255,255,255)','s_font':'rgb(255, 255, 255)'},
        'orange':{'c':(242,174,100),'p_font':'rgb(0,0,0)','s_font':'rgb(0,0,0)'},
        'purple':{'c':(114,88,136),'p_font':'rgb(255,255,255)','s_font':'rgb(255, 212, 55)'},
        'red':{'c':(255,0,0),'p_font':'rgb(0,0,0)','s_font':'rgb(0,0,0)'},
        'yellow':{'c':(255,255,0),'p_font':'rgb(0,0,0)','s_font':'rgb(27,53,81)'},
        'yellow_green':{'c':(232,240,165),'p_font':'rgb(0,0,0)','s_font':'rgb(0,0,0)'},
        'green':{'c':(65, 162, 77),'p_font':'rgb(217, 210, 192)','s_font':'rgb(0, 0, 0)'}
        }
    
    def add_color(image,c,transparency):
        color = Image.new('RGB',image.size,c)
        mask = Image.new('RGBA',image.size,(0,0,0,transparency))
        return Image.composite(image,color,mask).convert('RGB')
    
    def center_text(img,font,text1,text2,fill1,fill2):
        draw = ImageDraw.Draw(img)
        w,h = img.size
        t1_width, t1_height = draw.textsize(text1, font)
        t2_width, t2_height = draw.textsize(text2, font)
        p1 = ((w-t1_width)/2,h // 3)
        p2 = ((w-t2_width)/2,h // 3 + h // 5)
        draw.text(p1, text1, fill=fill1, font=font)
        draw.text(p2, text2, fill=fill2, font=font)
        return img
    
    def add_text(img,color,text1,text2,logo=False,font='Roboto-Bold.ttf',font_size=75):
        draw = ImageDraw.Draw(img)
    
        p_font = color['p_font']
        s_font = color['s_font']
        
        # starting position of the message
        img_w, img_h = img.size
        height = img_h // 3
        font = ImageFont.truetype(font,size=font_size)
    
        if logo == False:
            center_text(img,font,text1,text2,p_font,s_font)
        else:
            text1_offset = (img_w // 4, height)
            text2_offset = (img_w // 4, height + img_h // 5)
            draw.text(text1_offset, text1, fill=p_font, font=font)
            draw.text(text2_offset, text2, fill=s_font, font=font)
        return img
    
    def add_logo(background,foreground):
        bg_w, bg_h = background.size
        img_w, img_h = foreground.size
        img_offset = (20, (bg_h - img_h) // 2)
        background.paste(foreground, img_offset, foreground)
        return background
    
    def write_image(background,color,text1,text2,foreground=''):
        background = add_color(background,color['c'],25)
        if not foreground:
            add_text(background,color,text1,text2)
        else:
            add_text(background,color,text1,text2,logo=True)
            add_logo(background,foreground)
        return background
    
    if __name__ == '__main__':
        background = write_image(background,colors[color],text1,text2,foreground=foreground)
        background.save(img_name) 
        
    

    This is the end of the tutorial on how to create feature images from text using Python.

    1.9/5 - (11 votes)