Search code examples
pythonpython-3.xpython-imaging-librarypython-2.xpaste

Combine several images horizontally with Python


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']

# creates a new empty image, RGB mode, and size 444 by 95
new_im = Image.new('RGB', (444,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

Solution

  • 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