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
Test2.jpg
Test3.jpg
test.jpg
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')
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
Test2.jpg
Test3.jpg
Trifecta.jpg:
Trifecta_vertical.jpg
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()