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!).
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")
Provide the overlay alpha mask parameter and see if this yields results you expected:
background.paste(overlay, overlay.size, overlay)
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
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.
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
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!).
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")
Provide the overlay alpha mask parameter and see if this yields results you expected:
background.paste(overlay, overlay.size, overlay)
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
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.
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