Overlay two same sized images in Python

Question:

I’ve got two images that are exactly the same dimensions, all I’m trying to do is take one, make it 50% transparent and place it directly on top of the other, like so:

import Image

background = Image.open("bg.png")
overlay = Image.open("over.png")

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

background_pixels = background.load()
overlay_pixels = overlay.load()

for y in xrange(overlay.size[1]):
    for x in xrange(overlay.size[0]):
         background_pixels[x,y] = (background_pixels[x,y][0], background_pixels[x,y][1], background_pixels[x,y][2], 255)

for y in xrange(overlay.size[1]):
    for x in xrange(overlay.size[0]):
         overlay_pixels[x,y] = (overlay_pixels[x,y][0], overlay_pixels[x,y][1], overlay_pixels[x,y][2], 128)

background.paste(overlay)
background.save("new.png","PNG")

But all I get is the 50% transparent overlay (so half way there!).

Asked By: joedborg

||

Answers:

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")
Answered By: egor83

Provide the overlay alpha mask parameter and see if this yields results you expected:

background.paste(overlay, overlay.size, overlay)
Answered By: dolphin

Maybe too old question, can be done with ease using opencv

cv2.addWeighted(img1, alpha, img2, beta, gamma)
#setting alpha=1, beta=1, gamma=0 gives direct overlay of two images

Documentation link

Answered By: rainversion_3

The script here will also do the task using blend, it also has functionality to resize the images so as to make them the same size if they are not currently.

Answered By: Relative0

In case you want to resize them to the same shape:

b_h, b_w, b_ch = background.shape
W = 800
imgScale = W/b_w
new_b_h,new_b_w = int(b_h*imgScale), int(b_w*imgScale)
new_background = cv2.resize(background,(new_b_w, new_b_h))

Then you can fill in the shape fitting both background and foreground.

square= np.zeros((new_b_h, new_b_w, b_ch), np.uint8)
square.fill(255)
x= new_b_w
y= new_b_h
offset =0
square[int(y - new_b_h) - offset:int(y)- offset, int(x-new_b_w)- offset:int(x)- offset] = new_background 

Now you can overlay:

OPACITY = 0.7
added_image = cv2.addWeighted(new_background,OPACITY,square, 1-OPACITY, 0)

Details are on github

Answered By: Alex B
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.