Skip to content
Advertisement

Merging of Three Images in Single Row And Fourth Image in Next Row Using PIL In Python

I am trying to merge multiple images and as per requirement its working as explained below.

I am expecting 3 images should come in one single row and 4th image should come in next row but as per provided output for below image i am getting improper sequence of images i.e. Cat, Dog and Apple should come in one single row as per my code given below. Currently mouse image is also is coming with Cat, Dog and Apple as well as Apple image is not visible.

enter image description here

from PIL import Image

im1 = Image.open('cat_image.jpg')
im2 = Image.open('dog.jpg')
im3 = Image.open("apple.jpg")
im4 = Image.open("mouse.jpg")


def get_concat_h_multi_resize(im_list, resample=Image.BICUBIC):
    min_height = min(im.height for im in im_list)
    print("min_height", min_height)
    im_list_resize = [im.resize((int(im.width * min_height / im.height), min_height), resample=resample)
                      for im in im_list]
    total_width = sum(im.width for im in im_list_resize)
    print("total width", total_width)
    dst = Image.new('RGB', (total_width, min_height))
    pos_x,pos_y = 0,0
    img_counter = 0
    for im in im_list_resize:
        img_counter += 1
        if img_counter == 3:
            dst.paste(im, (pos_x, pos_y))
            pos_y += im.width + 5
        else:
            dst.paste(im, (pos_x, 0))
            pos_x += im.width + 5

    return dst


get_concat_h_multi_resize([im1, im2, im3, im4]).save('pillow_concat_h_multi_resize.jpg')

Expected Output :- I want to display Cat,Dog ,Apple in single row and mouse in next row.

Please help me with solution.

Thanks In Advance !!

Advertisement

Answer

You just need to use proper total_width and total_height in your output image. Since you need two rows, the total_height should be 2*min_height. The total_width should be just the sum of width of the first three images. Also, the x-coordinate for the new line should be 0 (or 5 since you are using a margin of width 5)

import math

from PIL import Image

im1 = Image.open("1.png")
im2 = Image.open("2.png")
im3 = Image.open("3.png")
im4 = Image.open("4.png")
im5 = Image.open("5.png")
im6 = Image.open("6.png")
im7 = Image.open("7.png")
im8 = Image.open("8.png")
im9 = Image.open("9.png")
im10 = Image.open("10.png")


def get_concat_h_multi_resize(im_list, n_rows, resample=Image.BICUBIC):
    min_height = min(im.height for im in im_list)

    im_list_resize = [
        im.resize((int(im.width * min_height / im.height), min_height), resample=resample) for im in im_list
    ]

    max_width = max(im.width for im in im_list_resize)

    n_cols = math.ceil(len(im_list) / n_rows)
    total_width = (max_width) * n_cols  # compute total width
    total_height = (min_height) * n_rows

    dst = Image.new("RGB", (total_width, total_height))  # calculate the total height

    pos_x = 0
    pos_y = 0
    for i in range(len(im_list_resize)):
        im = im_list_resize[i]
        dst.paste(im, (pos_y, pos_x))

        pos_y += im.width

        if (i + 1) % n_cols == 0:
            # new row
            pos_x += im.height
            pos_y = 0

    print(" total: ", total_width, total_height)
    return dst


get_concat_h_multi_resize(im_list=[im1, im2, im3, im4, im5, im6, im7, im8, im9, im10], n_rows=3).save(
    "pillow_concat_h_multi_resize.jpg"
)

The final output appears as shown below: enter image description here The trailing black areas in each row are because of reserving extra width to handle the image with maximum width. In this example, the number 10 has a larger width than the others, so we used the width of 10 to define our total width.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement