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.
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: 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.