2

This is basically the same question that was posted here: How to merge a transparent png image with another image using PIL but using with scikit-image instead of PIL. I mean to paste the png keeping its transparency on top of a background image. Also, if there is actually a way of doing it, I would like to know which one is faster (PIL or scikit-image). Thanks.

hipoglucido
  • 545
  • 1
  • 7
  • 20

2 Answers2

6

Read the two images and add using the formula img1*alpha + img2*(1-alpha)

import numpy as np
from matplotlib import pyplot as plt
import skimage.io

img1 = skimage.io.imread('Desert.jpg')
img2 = skimage.io.imread('Penguins.jpg')

img3 = np.ubyte(0.7*img1 + 0.3*img2)

plt.imshow(img3)

alpha merged image

Another option could be to use the alpha channel of two images as masks as below

import numpy as np
from matplotlib import pyplot as plt
import skimage.io

img1 = skimage.io.imread('img1.png')
img2 = skimage.io.imread('img2.png')

mask1 = img1.copy()
mask2 = img2.copy()

mask1[:,:,0] = mask1[:,:,3]
mask1[:,:,1] = mask1[:,:,3]
mask1[:,:,2] = mask1[:,:,3]

mask2[:,:,0] = mask2[:,:,3]
mask2[:,:,1] = mask2[:,:,3]
mask2[:,:,2] = mask2[:,:,3]

img3 = np.bitwise_or(np.bitwise_and(img1, mask1),np.bitwise_and(img2, mask2)) ;
plt.subplot(2,2,1)
plt.imshow(img1)
plt.subplot(2,2,2)
plt.imshow(img2)
plt.subplot(2,2,3)
plt.imshow(img3)

using alpha masks

dwitvliet
  • 7,242
  • 7
  • 36
  • 62
user8190410
  • 1,264
  • 2
  • 8
  • 15
  • 2
    The question was about merging a *"transparent PNG"* with another image, but your answer uses 2 JPEGs which don't support transparency... – Mark Setchell Dec 26 '18 at 14:03
2

Inspired by user8190410's answer, I built my own function to do it:

from skimage import data
import numpy as np

x, y = 100, 100
background = data.imread('background.jpg') / 255.
image = data.imread('image.png') / 255.

background_height, background_width, background_depth = background.shape
image_height, image_width, image_depth = image.shape

template = np.zeros((background_height, background_width, image_depth))
template[y : y + image_height, x : x + image_width, :] = image

mask = np.stack([template[:,:,3] for _ in range(3)], axis = 2)
inv_mask = 1. - mask
result = background[:,:,:3] * inv_mask + template[:,:,:3] * mask
plt.figure(figsize = (15, 15))
plt.subplot(1, 3, 2)
plt.imshow(image)
plt.subplot(1, 3, 1)
plt.imshow(background)
plt.subplot(1, 3, 3)
plt.imshow(result)
plt.tight_layout()
plt.show()

Image output

Please let me know if I can do something to improve computation speed

Community
  • 1
  • 1
hipoglucido
  • 545
  • 1
  • 7
  • 20
  • Please provide a **typical** foreground image that you want to overlay - so I can see whether it has binary or continuous transparency. – Mark Setchell Dec 27 '18 at 17:49