1

I want to merge multiple images into one single image horizontaly. I tried to merge images through given code but it gives white image? For merge Images I tried PIL .

Input1

Input2

Input3

output Image

import sys
from PIL import Image


def append_images(images,bg_color=(255,255,255), aligment='center'):

    widths, heights = zip(*(i.size for i in images))


    new_width = sum(widths)
    new_height = max(heights)


    new_im = Image.new('RGB', (new_width, new_height), color=bg_color)

    offset = 0
    for im in images:
        y = 0
        if aligment == 'center':
            y = int((new_height - im.size[1])/2)
        elif aligment == 'bottom':
            y = new_height - im.size[1]
        new_im.paste(im, (offset, y))
        offset += im.size[0]


    return new_im
date=input("Enter Date:")
l=['1.jpg','2.jpg','3.jpg']


images = map(Image.open,l)
combo_2 = append_images(images, aligment='center')
combo_2.save('combo_2.jpg')
stock_code
  • 23
  • 1
  • 6
  • Possible duplicate of [Combine several images horizontally with Python](https://stackoverflow.com/questions/30227466/combine-several-images-horizontally-with-python) – kabanus Mar 17 '19 at 14:16
  • The dupe target has also vertically. If this is not what you meant please say so (and explain how you want to merge the images). – kabanus Mar 17 '19 at 14:16
  • I think you're offsetting the images outside of the new image. – NoSplitSherlock Mar 17 '19 at 14:17

2 Answers2

1

I prefer working with OpenCV&Numpy combo. That means working with arrays. The code below simply take first image as starting point - Height. Any image you will append with it will be horizontaly stacked based on height. That means, appended image will be resized by the montage Height and then horizontally stacked to montage.

Working Code

import cv2
import numpy as np

image1 = cv2.imread("img1.jpg")[:,:,:3]
image2 = cv2.imread("img2.jpg")[:,:,:3]

class Montage(object):
    def __init__(self,initial_image):
        self.montage = initial_image
        self.x,self.y = self.montage.shape[:2]

    def append(self,image):
        image = image[:,:,:3]
        x,y = image.shape[0:2]
        new_image = cv2.resize(image,(int(y*float(self.x)/x),self.x))
        self.montage = np.hstack((self.montage,new_image))
    def show(self):
        cv2.imshow('montage',self.montage)
        cv2.waitKey()
        cv2.destroyAllWindows()

Firstly, you initialize class with first image which will define HEIGHT. So if you want different height, pass into the class resized image. After that you can append horizontaly the image

Usage

>>> m = Montage(image1)
>>> m.append(image2)
>>> m.show()

Result in your case: enter image description here


But generally it can work with totaly different sizes

Image 1

enter image description here

Image 2

enter image description here

Montage

enter image description here

Martin
  • 3,333
  • 2
  • 18
  • 39
1

Replace your line:

images = map(Image.open,l)

with:

images = [ Image.open(im) for im in l]

and it all works fine.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432