How to use alpha_composite in pillow?

Viewed 3024

I try to put a transparent logo on the photo with Pillow:

# First, I convert my photo and watermark to RGBA:
image = Image.open(photo_image_path).convert('RGBA')
watermark = Image.open(watermark_image_path).convert('RGBA')

# then I сreate an empty layer with the same size as image
# and put watermark in x/y position
layer = Image.new('RGBA', image.size, (0, 0, 0, 0))
layer.paste(watermark, (x, y))

# then add transparency 
layer.putalpha(128)

# and merge image with logo
result = Image.alpha_composite(image, layer)

Initially my watermark has a full-transparent background. But I have a result with black half-transparent background on all image size. What am I doing wrong?

3 Answers

I've resolved a problem with this:

image = Image.open(photo_image_path).convert('RGBA')
watermark = Image.open(watermark_image_path).convert('RGBA')
layer = Image.new('RGBA', image.size, (0, 0, 0, 0))
layer.paste(watermark, (x, y))

# Create a copy of the layer
layer2 = layer.copy()

# Put alpha on the copy
layer2.putalpha(128)

# merge layers with mask
layer.paste(layer2, layer)


result = Image.alpha_composite(image, layer)

When you do layer.putalpha(128) you replace the entire alpha channel of your overlay with "semitransparent", which is probably not what you want. My guess is that you want to multiply the alpha channel by one half. There is probably some more efficient way of doing that (which, now that I have exposed my ignorance, someone will certainly come along to inform us both about!), but at least this seems to work:

bands = layer.split()
if len(bands) != 4: raise Exception('Not an RGBA image')
adj_alpha = bands[3].point(lambda x: int(x * 0.5))
layer = image.merge('RGBA', [*bands[:3], adj_alpha])

a sample of my code with 5 layers

Generate Images

for item in all_images:

im1 = Image.open(f'./trait-layers/backgrounds/{background_files[item["Background"]]}.png').convert('RGBA')
im2 = Image.open(f'./trait-layers/shirt/{shirt_files[item["Shirt"]]}.png').convert('RGBA')
im3 = Image.open(f'./trait-layers/face/{face_files[item["Face"]]}.png').convert('RGBA')
im4 = Image.open(f'./trait-layers/eyes/{eyes_files[item["Eyes"]]}.png').convert('RGBA')
im5 = Image.open(f'./trait-layers/hair/{hair_files[item["Hair"]]}.png').convert('RGBA')
im6 = Image.open(f'./trait-layers/thing/{thing_files[item["Thing"]]}.png').convert('RGBA')

#Create each composite
com1 = Image.alpha_composite(im1, im2)
com2 = Image.alpha_composite(com1, im3)
com3 = Image.alpha_composite(com2, im4)
com4 = Image.alpha_composite(com3, im5)
com5 = Image.alpha_composite(com4, im6)



#Convert to RGB
rgb_im = com5.convert('RGB')
file_name = str(item["tokenId"]) + ".png"
rgb_im.save("./images/" + file_name)
Related