So for this project, I'm working on, I have 2 non-overlapping photos. These two photos need to be stitched together, one on the top and one on the bottom, and then you will be able to see the whole picture. Any ideas on what module I should use to do this?
-
4Do they overlap like a panorama? Or do you just need to make one bigger image by putting two smaller ones next to each other? – Leopd May 18 '12 at 18:05
5 Answers
Here's a code sample using Pillow. Hope it helps someone!
from PIL import Image
def merge_images(file1, file2):
"""Merge two images into one, displayed side by side
:param file1: path to first image file
:param file2: path to second image file
:return: the merged Image object
"""
image1 = Image.open(file1)
image2 = Image.open(file2)
(width1, height1) = image1.size
(width2, height2) = image2.size
result_width = width1 + width2
result_height = max(height1, height2)
result = Image.new('RGB', (result_width, result_height))
result.paste(im=image1, box=(0, 0))
result.paste(im=image2, box=(width1, 0))
return result

- 8,496
- 5
- 31
- 33
-
4this code works, I just tested it now. You can save the file by using this code -> merged = merge_images( file1, file2 ) merged.save( file_dest ) – fedmich Mar 31 '16 at 08:18
-
2The question was for one image on top of another, which is just flipping the actions on result_width with result_height – Ywapom Dec 13 '17 at 16:38
-
1@Ywapom Side-by-side works. I tried vertically (per the flip you suggested), however the bottom image is only black (empty?). Any advice? – boloyao Mar 29 '18 at 20:33
-
@boloyao changing the box argument in the second paste to (0,height1) works. – boloyao Mar 29 '18 at 20:37
The python imaging library (updated link) will eat that task for breakfast.
See the tutorial in particular the "Cutting, Pasting and Merging Images" section for some relevant help.
For rough outline, load both images with Image.open
, find out how big the output image will be by using the size
attribute and some addition, create the output image with Image.new
and then use the paste
method to past the two original images in.

- 3,558
- 1
- 18
- 38

- 52,955
- 12
- 126
- 132
-
2Could you elaborate a little bit on that? Like what functions I would use? Any tips? – Justin Gardner May 18 '12 at 17:59
-
7I added some hints to the answer. Normally I'd write a demo program but it has been a long week and a fine alcoholic beverage beckons ;-) – Nick Craig-Wood May 18 '12 at 18:06
-
1
-
1
-
Use numpy.hstack()
or numpy.vstack()
based on whether you want the images next to each other or on top of each other. You can transform your images into numpy arrays if they are some weird format that numpy doesn't accept. Make sure that you set dtype=np.uint8
if you interpret images as arrays using the np.asarray()
method.

- 85
- 1
- 9

- 41
- 1
-
1Please [edit](https://stackoverflow.com/posts/55408630/edit) your answer by formatting the text – mechnicov Mar 29 '19 at 00:08
-
2Would have been ore helpful if you actually provided a code example. – not2qubit Nov 23 '19 at 15:07
This is some code from Jan Erik Solems computer vision with python book; you can probably edit it to fit your top/bottom needs
def stitchImages(im1,im2):
'''Takes 2 PIL Images and returns a new image that
appends the two images side-by-side. '''
# select the image with the fewest rows and fill in enough empty rows
rows1 = im1.shape[0]
rows2 = im2.shape[0]
if rows1 < rows2:
im1 = concatenate((im1,zeros((rows2-rows1,im1.shape[1]))), axis=0)
elif rows1 > rows2:
im2 = concatenate((im2,zeros((rows1-rows2,im2.shape[1]))), axis=0)
# if none of these cases they are equal, no filling needed.
return concatenate((im1,im2), axis=1)

- 1,373
- 3
- 16
- 24
I did vertical stitching like this - it is same code from @d3ming
07: def merge_images(file1, file2):
08: """Merge two images into one vertical image
09: :param file1: path to first image file
10: :param file2: path to second image file
11: :return: the merged Image object
12: """
13: image1 = Image.open(file1)
14: image2 = Image.open(file2)
15:
16: (width1, height1) = image1.size
17: (width2, height2) = image2.size
18:
19: # result_width = width1 + width2
20: result_width = width1
21: # result_height = max(height1, height2)
22: result_height = height1 + height2
23:
24: print (height2)
25:
26: result = Image.new('RGB', (result_width, result_height))
27: result.paste(im=image1, box=(0, 0))
28: result.paste(im=image2, box=(0, height1))
29: return result
line 19-22 - only height will change for stitching
paste the second image on line-28 box=(width1, 0)
changes to box=(0, height1)

- 85
- 1
- 9