Combine several images horizontally with Python Combine several images horizontally with Python python python

Combine several images horizontally with Python


You can do something like this:

import sysfrom PIL import Imageimages = [Image.open(x) for x in ['Test1.jpg', 'Test2.jpg', 'Test3.jpg']]widths, heights = zip(*(i.size for i in images))total_width = sum(widths)max_height = max(heights)new_im = Image.new('RGB', (total_width, max_height))x_offset = 0for im in images:  new_im.paste(im, (x_offset,0))  x_offset += im.size[0]new_im.save('test.jpg')

Test1.jpg

Test1.jpg

Test2.jpg

Test2.jpg

Test3.jpg

Test3.jpg

test.jpg

enter image description here


The nested for for i in xrange(0,444,95): is pasting each image 5 times, staggered 95 pixels apart. Each outer loop iteration pasting over the previous.

for elem in list_im:  for i in xrange(0,444,95):    im=Image.open(elem)    new_im.paste(im, (i,0))  new_im.save('new_' + elem + '.jpg')

enter image description hereenter image description hereenter image description here


I would try this:

import numpy as npimport PILfrom PIL import Imagelist_im = ['Test1.jpg', 'Test2.jpg', 'Test3.jpg']imgs    = [ PIL.Image.open(i) for i in list_im ]# pick the image which is the smallest, and resize the others to match it (can be arbitrary image shape here)min_shape = sorted( [(np.sum(i.size), i.size ) for i in imgs])[0][1]imgs_comb = np.hstack( (np.asarray( i.resize(min_shape) ) for i in imgs ) )# save that beautiful pictureimgs_comb = PIL.Image.fromarray( imgs_comb)imgs_comb.save( 'Trifecta.jpg' )    # for a vertical stacking it is simple: use vstackimgs_comb = np.vstack( (np.asarray( i.resize(min_shape) ) for i in imgs ) )imgs_comb = PIL.Image.fromarray( imgs_comb)imgs_comb.save( 'Trifecta_vertical.jpg' )

It should work as long as all images are of the same variety (all RGB, all RGBA, or all grayscale). It shouldn't be difficult to ensure this is the case with a few more lines of code. Here are my example images, and the result:

Test1.jpg

Test1.jpg

Test2.jpg

Test2.jpg

Test3.jpg

Test3.jpg

Trifecta.jpg:

combined images

Trifecta_vertical.jpg

enter image description here


Edit: DTing's answer is more applicable to your question since it uses PIL, but I'll leave this up in case you want to know how to do it in numpy.

Here is a numpy/matplotlib solution that should work for N images (only color images) of any size/shape.

import numpy as npimport matplotlib.pyplot as pltdef concat_images(imga, imgb):    """    Combines two color image ndarrays side-by-side.    """    ha,wa = imga.shape[:2]    hb,wb = imgb.shape[:2]    max_height = np.max([ha, hb])    total_width = wa+wb    new_img = np.zeros(shape=(max_height, total_width, 3))    new_img[:ha,:wa]=imga    new_img[:hb,wa:wa+wb]=imgb    return new_imgdef concat_n_images(image_path_list):    """    Combines N color images from a list of image paths.    """    output = None    for i, img_path in enumerate(image_path_list):        img = plt.imread(img_path)[:,:,:3]        if i==0:            output = img        else:            output = concat_images(output, img)    return output

Here is example use:

>>> images = ["ronda.jpeg", "rhod.jpeg", "ronda.jpeg", "rhod.jpeg"]>>> output = concat_n_images(images)>>> import matplotlib.pyplot as plt>>> plt.imshow(output)>>> plt.show()

enter image description here