Combine several images horizontally with Python

ghz 3months ago ⋅ 30 views

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

Answers

You can horizontally concatenate the images more effectively by correcting a couple of things in your code. The issue arises because you are pasting the same image multiple times inside the for i in xrange(0,444,95) loop, which is unnecessary. Instead, you can calculate the correct width dynamically based on the number of images and their sizes, and then paste each image one after the other.

Here’s a modified solution that avoids hard-coding the dimensions and works for any number of images:

Solution:

from PIL import Image

# List of images to concatenate
list_im = ['Test1.jpg', 'Test2.jpg', 'Test3.jpg']

# Open all images and store them in a list
imgs = [Image.open(i) for i in list_im]

# Get the width and height of the first image
width, height = imgs[0].size

# Create a new empty image with the combined width and the height of one image
total_width = width * len(imgs)
new_im = Image.new('RGB', (total_width, height))

# Paste each image into the new image, one after another horizontally
x_offset = 0
for im in imgs:
    new_im.paste(im, (x_offset, 0))
    x_offset += im.width

# Save the combined image
new_im.save('test.jpg')

Explanation:

  • Dynamic width calculation: total_width = width * len(imgs) dynamically calculates the width of the new image by multiplying the width of a single image by the number of images.
  • Pasting images: The loop pastes each image into the new image using the correct x_offset that increments after each paste.
  • Image dimensions: The width and height of the images are fetched dynamically using imgs[0].size, ensuring the code works for images of any size.

Output:

This will create a new image (test.jpg) with your images concatenated horizontally without any partial overlaps or distortions.