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
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.