Make covers with PIL

Changes on the code to make covers

I made an updated version of the code to make cover images with Python. I made this in jupyter lab (that is why I put speak.imgb to see the image in the notebook itself.

The styles dictionary

In this dictionary I’ve collected the data to adjust the position of the text and image in the image so that they looks good to me. Having this dictionary with each key resambling the size of the image, helps me to use the code for different size of the covers without having too much work changing the absolute position of them. It shoulb be a nice implementation to make the position of the element relative to the different sizes of the images, but this can also make future possible adaptations that can involve also pasting 2 or 3 images together and more, so I think I will leave the absolute position with the chance to add more styles in a next future. So, I think now it is quite intuive the use of the code and the mantainance should be pretty easy.

image_vertical_adjustment

This variable is to make the image at the center go a little up or down, depending on the height of the image. So 4 will put the image higher than 5.

ratio

The ratio variable now can use decimal number now for more precise resizing respecting always the width and height ratio.

 

from PIL import Image, ImageFont, ImageDraw
import os

class App:
    """num_img is to allow to put 2 images on the cover
    size = {size,title_font,subtitle_font,pos1,pos2}
    img_vertical adjustment makes the image (central) go down when 4 becomes 5
    """
    def __init__(self, title="", subtitle="", image="", bg="",ratio=2,
                 size={}, num_img=1,
                filename="image", num=1,
                image_vertical_adjustment=4):
        self.size = size["size"]
        self.bg = bg
        self.img = image
        self.shrink_ratio = ratio # use this in case you need to resize the image in the middle
        self.font = "arial", size["font1"]
        self.title = title
        self.subtitle = subtitle
        self.filename = "output\\" + filename + str(num) + "_cover.png" # do not need to change this
        self.fnt = ImageFont.truetype(self.font[0], self.font[1])
        self.fnt2 = ImageFont.truetype("arial", size["font2"])
        self.imgb = Image.new("RGB", (self.size), color=self.bg)
        self.num_img = num_img
        self.pos1 = size['pos1']
        self.pos2 = size['pos2']
        self.image_vertical_adjustment = image_vertical_adjustment
        print("Use create_image() method to see the picture.")
        print(f"You find the file in {self.filename}")


    def shrink(self, link, ratio=2):
        """Returns an image that is half of the original if ratio=2"""
        img = Image.open(link)
        w,h = img.size
        w = int(w // ratio) # 2 is 50%
        h = int(h // ratio)
        img = img.resize((w,h), Image.ANTIALIAS)
        return img
        
    def middle(self, img, m=2):
        """Return the coordinates to place the image in the middle"""
        return self.size[0] // m - img.size[0] // m, self.size[1] // 2 - img.size[1] //  self.image_vertical_adjustment

    def create_image(self):
        self.draw = ImageDraw.Draw(self.imgb)
        self.title = self.title
        self.subtitle = self.subtitle
        self.draw.text(self.pos1, self.title, font=self.fnt)
        self.draw.text(self.pos2, self.subtitle, font=self.fnt2)
        if self.num_img == 1:
           self.img_middle = self.shrink(self.img, self.shrink_ratio)
           self.half4 = (self.middle(self.img_middle,2))
           self.imgb.paste(self.img_middle, self.half4, self.img_middle)
           self.imgb.save(self.filename)

     # DIFFERENT STYLES DEPENDING ON THE SIZE OF THE COVER    
    
styles_by_size = {
    "280x200" : {
                "size" :(280, 200),
                "font1" : 24,
                "font2" : 14,
                "pos1" : (20,20),
                "pos2" : (20,50)
            },

    "600x400" : {
            "size" :(600, 400),
            "font1" : 72,
            "font2" : 36,
            "pos1" : (48,30),
            "pos2" : (48,80)
    }
}
    
speak = App(
        title="Pythonprogramming",
        subtitle="Examples in Python",
        image= "py.png",
        bg= "navy",
        ratio=1.2,
        size = styles_by_size["280x200"],
        num_img = 1,
        filename = "myblog",
        num = 2,
        image_vertical_adjustment = 4
        )

speak.create_image()
speak.imgb
speak.show()

 

Out[50]:

Other article about the evolution of this code

create a cover image with PIL

tkinter app to resize images

transfrom code of cover maker app into a class

Published by pythonprogramming

Started with basic on the spectrum, loved javascript in the 90ies and python in the 2000, now I am back with python, still making some javascript stuff when needed.