Combine several images horizontally with Python

edesz picture edesz · May 14, 2015 · Viewed 170.6k times · Source

I am trying to horizontally combine some JPEG images in Python.

Problem

I have 3 images - each is 148 x 95 - see attached. I just made 3 copies of the same image - that is why they are the same.

enter image description hereenter image description hereenter image description here

My attempt

I am trying to horizontally join them using the following code:

import sys
from PIL import Image

list_im = ['Test1.jpg','Test2.jpg','Test3.jpg']
new_im = Image.new('RGB', (444,95)) #creates a new empty image, RGB mode, and size 444 by 95

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('test.jpg')

However, this is producing the output attached as test.jpg.

enter image description here

Question

Is there a way to horizontally concatenate these images such that the sub-images in test.jpg do not have an extra partial image showing?

Additional Information

I am looking for a way to horizontally concatenate n images. I would like to use this code generally so I would prefer to:

  • not to hard-code image dimensions, if possible
  • specify dimensions in one line so that they can be easily changed

Answer

dting picture dting · May 14, 2015

You can do something like this:

import sys
from PIL import Image

images = [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 = 0
for 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 here enter image description here enter image description here