Search code examples
pythonpython-imaging-libraryimage-manipulation

How do I fix my image not being pasted correctly?


I am trying to crop a image into a circulor form (which works) and then pasting it to a white backround.

from PIL import Image,ImageFont,ImageDraw, ImageOps, ImageFilter
from io import BytesIO
import numpy as np



pfp = Image.open(avatar)

# cropping to circle
img=pfp.convert("RGB")
npImage=np.array(img)
h,w=img.size

alpha = Image.new('L', img.size,0)
draw = ImageDraw.Draw(alpha)
draw.pieslice([0,0,h,w],0,360,fill=255)
npAlpha=np.array(alpha)
npImage=np.dstack((npImage,npAlpha))
Image.fromarray(npImage).save('result.png')

background = Image.open('white2.png')

background.paste(Image.open('result.png'), (200, 200, h, w))
background.save('combined.png')

Heres what the cropped image looks like(It looks like it has a white background but that's it's transparent): Cropped Image

But then when I paste it to the white background it changes to a square: Pasted Image

Here is the original image I am working with: Image


Solution

  • What you're doing is setting the Alpha of any pixel outside that circle to 0, so when you render it, it's gone, but that pixel data is still there. That's not a problem, but it important to know.

    Problem
    Your "white2.png" image does not have an alpha channel. Even if it's a PNG file, you have to add an alpha channel using your image editing tool. You can print("BGN:", background.getbands()), to see the channels it has. You'll see it says 'R','G','B', but no 'A'.

    Solution 1
    Replace your paste line with:
    background.paste(pfp, (200, 200), alpha)
    Here, we use the loaded in avatar as is, and the third argument is a mask which PIL figures out how to use to mask the image before pasting.

    Solution 2
    Give your white background image an alpha channel.
    MS Paint doesn't do this. You have to use something else.
    For GIMP, you simply right-click on the layer and click Add Alpha-channel.

    Oh, and something worth noting.
    Documentation for Paste.

    See alpha_composite() if you want to combine images with respect to their alpha channels.