waspinator
waspinator

Reputation: 6826

draw multiple transparent masks on an image

I have an image and some binary masks I want to apply to the image to highlight certain areas. I'm able to draw one mask, but each subsequent applied mask lightens the previous mask and the original image more and more.

How can I apply multiple masks while keeping each mask and the image brightness constant?

import numpy as np
import matplotlib
from matplotlib.pyplot import imshow
from PIL import Image, ImageDraw, ImageFont
import requests

matplotlib.rcParams['figure.figsize'] = (20.0, 10.0)

url = 'https://upload.wikimedia.org/wikipedia/commons/thumb/e/ee/Grumpy_Cat_by_Gage_Skidmore.jpg/480px-Grumpy_Cat_by_Gage_Skidmore.jpg'
image = (Image.open(requests.get(url, stream=True).raw)).convert('RGBA')

annotation1 = (np.ones((image.size[1], image.size[0], 3))*255).astype(np.uint8)
annotation1[350:400, 50:450] = (255, 0, 0)
mask1 = (np.zeros((image.size[1], image.size[0])))
mask1[350:400, 50:450] = 1
mask1 = Image.fromarray(mask1, mode='1')

annotation2 = (np.ones((image.size[1], image.size[0], 3))*255).astype(np.uint8)
annotation2[400:450, 50:450] = (255, 0, 0)
mask2 = (np.zeros((image.size[1], image.size[0])))
mask2[350:400, 50:450] = 1
mask2 = Image.fromarray(mask2, mode='1')

annotation1 = Image.fromarray(annotation1, mode='RGB').convert('RGBA')
annotation2 = Image.fromarray(annotation2, mode='RGB').convert('RGBA')
annotation1.putalpha(128)
annotation2.putalpha(128)

image = Image.alpha_composite(image, annotation1)
image = Image.alpha_composite(image, annotation2)
imshow(image)

I have also tried using Image.composite(), but it only shows the mask and whites out the rest of the image.

image = Image.composite(image, annotation1, mask1)

enter image description here

Upvotes: 5

Views: 3718

Answers (1)

waspinator
waspinator

Reputation: 6826

You can use ImageDraw.bitmap(xy, bitmap, fill=None) to draw masks from bitmaps. You can have multiple shades per mask, but only one color.

url = 'https://upload.wikimedia.org/wikipedia/commons/thumb/e/ee/Grumpy_Cat_by_Gage_Skidmore.jpg/480px-Grumpy_Cat_by_Gage_Skidmore.jpg'
image = (Image.open(requests.get(url, stream=True).raw)).convert('RGBA')
image.putalpha(128)

mask1 = (np.zeros((image.size[1], image.size[0]))).astype(np.uint8)
mask1[350:400, 50:450] = 255
mask1 = Image.fromarray(mask1, mode='L')

mask2 = (np.zeros((image.size[1], image.size[0]))).astype(np.uint8)
mask2[410:460, 50:450] = 255
mask2[415:455, 55:445] = 128
mask2 = Image.fromarray(mask2, mode='L')

overlay = Image.new('RGBA', image.size, (255,255,255,0))
drawing = ImageDraw.Draw(overlay)
drawing.bitmap((0, 0), mask1, fill=(255, 0, 0, 128))
drawing.bitmap((0, 0), mask2, fill=(255, 0, 0, 128))

image = Image.alpha_composite(image, overlay)

imshow(image)

enter image description here

Upvotes: 5

Related Questions