I have two functions.
The first one changes the opacity of all black pixels in the overlay image to 0.
The second image overlays onto another one with changing opacity. But only for all pixels that are not black.
Overall I want to overlay images with different opacities and prevent that the black background does not show up.
It works just fine, but not really fast (both avg > 2sec). Is there a way to speed up the process a little? Numpy for example?
Here is what I have so far:
def remove_background(image):
im = image.convert('RGBA')
w, h = im.size
for i in range(w):
for j in range(h):
cordinate = i, j
rgb_map = im.getpixel(cordinate)
if rgb_map == (0, 0, 0, 255):
im.putpixel(cordinate, (0, 0, 0, 0))
return im
def overlay_image(background, overlay, opacity=0.5):
background = background.convert('RGBA')
overlay = overlay.convert('RGBA')
opacity = int(opacity * 255)
w, h = background.size
for i in range(w):
for j in range(h):
cordinate = i, j
rgb_map = overlay.getpixel(cordinate)
r = rgb_map[0]
g = rgb_map[1]
b = rgb_map[2]
if r == 64 and g == 128 and b == 19:
overlay.putpixel(cordinate, (64, 128, 19, opacity))
background.paste(overlay, (0,0), overlay)
return background
I know there is something from PIL
called Image.blend()
, but this is just for the whole image and not for certain pixels.
Here is an example I want to overlay:
animal
mask
result
Updated Answer
I think this is what your updated question is looking for:
#!/usr/bin/env python3
from PIL import Image
# Open the mask, discarding any alpha channel
mask = Image.open('mask.png').convert('RGB')
# Generate a new alpha channel that is transparent wherever the mask is black
alpha = mask.copy()
alpha = alpha.convert('L')
alpha.point(lambda p: 128 if p > 0 else 0)
# Open the animal, discarding its pointless alpha channel
animal = Image.open('animal.png').convert('RGB')
# Paste the mask over the animal, respecting transparency
animal.paste(mask,mask=alpha)
animal.save('result.png')
Alternative
As an alternative, you could simply add the mask to the animal. Where the mask is black (ie zero) it will add nothing:
#!/usr/bin/env python3
from PIL import Image, ImageChops
# Open the mask, discarding any alpha channel
mask = Image.open('mask.png').convert('RGB')
# Open the animal, discarding any alpha channel
animal = Image.open('animal.png').convert('RGB')
# Add the mask to the animal
res = ImageChops.add(animal, mask)
res.save('result.png')
You could scale the mask first, say by a half, using Image.point()
with a lambda like below, if the green is too much.
Original Answer
Mmmm, if you want to mask an input image with another input image and show the results, I think you'd need three images, not two.
So, I am guessing this is what you want and it should be nice and fast:
#!/usr/bin/env python3
from PIL import Image
# Open the mask, discarding its pointless alpha channel and colour information
mask = Image.open('mask.png').convert('L')
# Generate a new alpha channel that is transparent wherever the mask is black
mask.point(lambda p: 255 if p > 0 else 0)
# Open the animal, discarding its pointless alpha channel
animal = Image.open('animal.png').convert('RGB')
# Put our lovely new alpha channel into animal image and save
animal.putalpha(mask)
animal.save('result.png')
mask.png
animal.png
Just for fun, here's another way of doing it leveraging Numpy:
#!/usr/bin/env python3
from PIL import Image
import numpy as np
# Open the overlay and animal, discarding any alpha channel
overlay = Image.open('mask.png').convert('RGB')
animal = Image.open('animal.png').convert('RGB')
mask = overlay.convert('L')
# Make into Numpy arrays
overlay= np.array(overlay)
animal = np.array(animal)
mask = np.array(mask)
# Blend animal and overlay
blended = animal//2 + overlay//2
# Choose blended or original at each location depending on mask
res = np.where(mask[...,np.newaxis], blended, animal)
# Revert to PIL Image and save
Image.fromarray(res).save('result.png')
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.