Try using blend() instead of paste() - it seems paste() just replaces the original image with what you're pasting in.

try:
    from PIL import Image
except ImportError:
    import Image

background = Image.open("bg.png")
overlay = Image.open("ol.jpg")

background = background.convert("RGBA")
overlay = overlay.convert("RGBA")

new_img = Image.blend(background, overlay, 0.5)
new_img.save("new.png","PNG")
Answer from egor83 on Stack Overflow
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ python โ€บ overlay-an-image-on-another-image-in-python
Overlay an image on another image in Python - GeeksforGeeks
July 23, 2025 - Firstly we opened the primary image and saved its image object into variable img1. Then we opened the image that would be used as an overlay and saved its image object into variable img2.
๐ŸŒ
Quora
quora.com โ€บ How-can-I-overlay-2-images-of-different-sizes-using-Python
How to overlay 2 images of different sizes using Python - Quora
Answer (1 of 2): overlay of 2 images of different sizes I posted details on github: pydemo/overlay Background image Foreground image Get images width/height [code]b_h, b_w, b_ch = background.shape o_h, o_w, o_ch = overlay.shape [/code]Scale background image [code] W = 800 imgScale =...
๐ŸŒ
GitHub
github.com โ€บ pydemo โ€บ overlay
GitHub - pydemo/overlay: Overlay 2 images using python and OpenCV ยท GitHub
#OVERLAY OPACITY = 0.7 added_image = cv2.addWeighted(new_background,0.6,square,0.4,0) cv2.imshow('adjusted', added_image) cv2.waitKey() cv2.imwrite(out, added_image)
Author: pydemo
๐ŸŒ
Plotly
community.plotly.com โ€บ ๐Ÿ“Š plotly python
How to overlay two images with opacity - ๐Ÿ“Š Plotly Python - Plotly Community Forum
June 7, 2023 - I have a simple problem, I want to overlay two rgb images (np.arrays with three channels and same size) over each other, with opacity setting for the top so I can see both. fig_visual_check = go.Figure() fig_visual_check = fig_visual_check.add_trace(go.Image(z=images_merged_visual[0], opacity=0.5)) fig_visual_check = fig_visual_check.add_trace(go.Image(z=images_merged_visual[1], opacity=1)) fig_visual_check However, the result is just a black image.
๐ŸŒ
Educative
educative.io โ€บ answers โ€บ how-to-superimpose-two-images-using-pil-in-python
How to superimpose two images using PIL in Python
The Image module offers a variety of factory operations, including tools for generating new pictures and loading images from files. Two images can be superimposed on another using the paste() function from the Image module.
Top answer
1 of 1
1

There are two issues:

  • The math is incorrect:

subtracted_image = ImageChops.subtract(image2, image1)
==> subtracted_image = image2 - image1

reversed_image = ImageChops.add(image2, subtracted_image)
==> reversed_image = image2 + subtracted_image
==> reversed_image = image2 + (image2 - image1)
==> reversed_image = image2*2 - image1

As you can see the math is wrong.
The correct statement is:
reversed_image = ImageChops.add(image1, subtracted_image)
==> reversed_image = image1 + (image2 - image1)
==> reversed_image = image2


  • The second issue is that ImageChops.subtract and ImageChops.add are not reversible operations.
    That is because the data type is uint8, and can't have negative values (and can't have values above 255).
    When using ImageChops.subtract, all negative values are clipped to zero.
    When using ImageChops.add, all values above 255 are clipped to 255.
    The clipping to range [0, 255] loses data, and we are not getting the original image.

There is a nice explanation in the following post.


We may use ImageChops.subtract_modulo and ImageChops.add_modulo, which are reversible.
The math is not intuitive, but it's working:

from PIL import Image, ImageChops

# Load the images
image1 = Image.open('image1.jpg')
image2 = Image.open('image2.jpg')

# Subtract image2 from image1
subtracted_image = ImageChops.subtract_modulo(image1, image2)  # image1 - image2

reversed_image = ImageChops.add_modulo(image2, subtracted_image)  # image2 + (image1 - image2)

# Display the reversed image
reversed_image.show() 

More intuitive solution is converting the images to NumPy arrays with type dtype np.int32 or np.int16.
Then subtract and add the NumPy arrays.
The advantage is that np.int32 or np.int16 types may hold positive and negative values, and have a larger range that avoids arithmetic overflow.

Find elsewhere
๐ŸŒ
Moonbooks
moonbooks.org โ€บ Articles โ€บ How-to-overlay--superimpose-two-images-using-python-and-pillow-
How to overlay / superimpose two images using python and pillow ?
August 24, 2022 - from PIL import Image import numpy as np img = Image.open("data_mask_1354_2030.png") background = Image.open("background_1354_2030.png") background.paste(img, (0, 0), img) background.save('how_to_superimpose_two_images_01.png',"PNG")
๐ŸŒ
YouTube
youtube.com โ€บ watch
How to Overlay 2 Images Using Python Tutorial! - YouTube
This is a basic Python tutorial/program to help you get started on overlay images!Source Code:https://github.com/RykerSwensen/basic_python_programs/tree/mast...
Published: February 16, 2023
๐ŸŒ
Readthedocs
plantcv.readthedocs.io โ€บ en โ€บ latest โ€บ visualize_ovelay_two_imgs
Overlay Images - PlantCV - Read the Docs
This function overlays one input image on top of the other one, with a desired alpha value indicating the opacity of the 1st image. It is able to handle both RGB and gray scale images. plantcv.visualize.overlay_two_imgs(img1, img2, alpha=0.5)
๐ŸŒ
PyImageSearch
pyimagesearch.com โ€บ home โ€บ blog โ€บ transparent overlays with opencv
Transparent overlays with OpenCV - PyImageSearch
April 17, 2021 - In order to apply the transparent overlay, we need to make two copies of the input image:
๐ŸŒ
Python Examples
pythonexamples.org โ€บ pillow-image-overlay
Image Overlaying in Python with Pillow
In this tutorial, you will learn how to use Image.paste() to over an image over another. The steps to overlay an image over another image with Pillow are ยท Import Image module from Pillow library. Read the two input images using Image.open() function, say base_img and overlay_img.
Top answer
1 of 1
9

A solution upfront.

Background image

width/height/ratio: 300 / 375 / 0.800

Foreground image

width/height/ratio: 400 / 464 / 0.862

Overlay

from PIL import Image

imbg = Image.open("bg.png")
imfg = Image.open("fg.png")
imbg_width, imbg_height = imbg.size
imfg_resized = imfg.resize((imbg_width, imbg_height), Image.LANCZOS)
imbg.paste(imfg_resized, None, imfg_resized)
imbg.save("overlay.png")

Discussion

The most important information you have given in your question were:

  • the aspect ratios of your foreground and background images are not equal, but similar
  • the top left and bottom right corners of both images need to be aligned in the end.

The conclusion from these points is: the aspect ratio of one of the images has to change. This can be achieved with the resize() method (not with thumbnail(), as explained below). To summarize, the goal simply is:

Resize the image with larger dimensions (foreground image) to the exact dimensions of the smaller background image. That is, do not necessarily maintain the aspect ratio of the foreground image.

That is what the code above is doing.

Two comments on your approach:

First of all, I recommend using the newest release of Pillow (Pillow is the continuation project of PIL, it is API-compatible). In the 2.7 release they have largely improved the image re-scaling quality. The documentation can be found at http://pillow.readthedocs.org/en/latest/reference.

Then, you obviously need to take control of how the aspect ratio of both images evolves throughout your program. thumbnail(), for instance, does not alter the aspect ratio of the image, even if your size tuple does not have the same aspect ratio as the original image. Quote from the thumbnail() docs:

This method modifies the image to contain a thumbnail version of itself, no larger than the given size. This method calculates an appropriate thumbnail size to preserve the aspect of the image

So, I am not sure where you were going exactly with your (643,597) tuple and if you are possibly relying on the thumbnail to have this exact size afterwards.

๐ŸŒ
Pythontic
pythontic.com โ€บ image-processing โ€บ pillow โ€บ blend
Blend two images using an alpha value | Pythontic.com
The blend() method of Pillow library blends two images with an alpha value. The Python example uses two alpha values - 0.2 and 0.4 producing two output images.
๐ŸŒ
Matplotlib
matplotlib.org โ€บ stable โ€บ gallery โ€บ images_contours_and_fields โ€บ layer_images.html
Layer images with alpha blending โ€” Matplotlib 3.11.2 documentation
import matplotlib.pyplot as plt import numpy as np def func3(x, y): return (1 - x / 2 + x**5 + y**3) * np.exp(-(x**2 + y**2)) # make these smaller to increase the resolution dx, dy = 0.05, 0.05 x = np.arange(-3.0, 3.0, dx) y = np.arange(-3.0, 3.0, dy) X, Y = np.meshgrid(x, y) # when layering multiple images, the images need to have the same # extent.
๐ŸŒ
Stack Overflow
stackoverflow.com โ€บ questions โ€บ 45598317 โ€บ overlay-multiple-images-in-python
Overlay multiple images in python - Stack Overflow
August 10, 2017 - Currently I am searching the way to do it, ... One approach is to store all your images as a list, and then iterate through each overlapping pair of images and callcv2.addWeighted() on each element in your list, passing in the last aggregate ...
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ python โ€บ transparent-overlays-with-python-opencv
Transparent overlays with Python OpenCV - GeeksforGeeks
July 23, 2025 - import cv2 import numpy as np # Loading our images # Background/Input image background = cv2.imread('Assets/img1.jpg') # Overlay image overlay_image = cv2.imread('Assets/overlay3.png') # Resize the overlay image to match the bg image dimensions overlay_image = cv2.resize(overlay_image, (1000, 1000)) h, w = overlay_image.shape[:2] # Create a new np array shapes = np.zeros_like(background, np.uint8) # Put the overlay at the bottom-right corner shapes[background.shape[0]-h:, background.shape[1]-w:] = overlay_image # Change this into bool to use it as mask mask = shapes.astype(bool) # We'll create
๐ŸŒ
PyTorch Forums
discuss.pytorch.org โ€บ t โ€บ how-to-overlay-two-images โ€บ 149081
How to overlay two images? - PyTorch Forums
April 13, 2022 - Hello, I want to overlay two images, the one of hair and the one of skin. When I try this code: blended = Image.blend(im1, im2, alpha=0.2) I get the result in Image 3 which is different from the result I am loโ€ฆ