Skip to content Skip to sidebar Skip to footer

Masking Two Images And Merge Into One Image

I am working on a project where I am using different masks on two different pictures and than would like to combine them into one picture. So far I have the masking (albeit it has

Solution 1:

To you points:

  1. You problem with masking simply orginiates from the fact that your masks are not perfect. Open them in paint and you will see that on the top side, there is a white line remaining. Just use the fill in tool to fill that white part with black. Afterwards it should work.

  2. I suggest mirroring your image horizontally instead of rotating it. You can use PIL.ImageOps.mirror for that. Then you paste one image onto the other image using img.paste(). As a second argument, you give the coordinates where the image should be pasted onto the other, and very importantly, as a third argument, you specify a transparency mask. Since your image already has an alpha channel, you can just use the same image as a mask. PIL will automatically use it's alpha channel for masking. Note that I had to adjust the position of pasting by 4 pixels to overlap the images correctly.

from PIL import Image, ImageOps

# load images
img_day  = Image.open('day.jpg')
img_night  = Image.open('night.jpg')
night_mask = Image.open('night_mask.jpg')
day_mask = Image.open('day_mask.jpg')

# convert images
#img_org  = img_org.convert('RGB') # or 'RGBA'
night_mask = night_mask.convert('L')    # grayscale
day_mask = day_mask.convert('L')

# the same size
img_day  = img_day.resize((750,750))
img_night  = img_night.resize((750,750))
night_mask = night_mask.resize((750,750))
day_mask = day_mask.resize((750,750))
# add alpha channel    

img_day.putalpha(day_mask)
img_night.putalpha(night_mask)
img_night = ImageOps.mirror(img_night)


img_night.paste(img_day, (-4, 0), img_day)
img_night.save('composite.png')

Result:

enter image description here


Solution 2:

The main problem are the (JPG) artifacts in your masks (white line at the top, "smoothed" edges). Why not use ImageDraw.arc to generate the masks on-the-fly? The final step you need is to use Image.composite to merge your two images.

Here's some code (I took your first image as desired output, thus the chosen angles):

from PIL import Image, ImageDraw

# Load images
img_day = Image.open('day.jpg')
img_night = Image.open('night.jpg')

# Resize images
target_size = (750, 750)
img_day = img_day.resize(target_size)
img_night = img_night.resize(target_size)

# Generate proper masks
day_mask = Image.new('L', target_size)
draw = ImageDraw.Draw(day_mask)
draw.arc([10, 10, 740, 740], 120, 270, 255, 150)
night_mask = Image.new('L', target_size)
draw = ImageDraw.Draw(night_mask)
draw.arc([10, 10, 740, 740], 270, 120, 255, 150)

# Put alpha channels
img_day.putalpha(day_mask)
img_night.putalpha(night_mask)

# Compose and save image
img = Image.composite(img_day, img_night, day_mask)
img.save('img.png')

That'd be the output:

Output

----------------------------------------
System information
----------------------------------------
Platform:    Windows-10-10.0.16299-SP0
Python:      3.8.5
Pillow:      8.0.1
----------------------------------------

Post a Comment for "Masking Two Images And Merge Into One Image"