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.
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
.
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.