I prefer using OpenCV but we can do it with PIL.
- Replace white with transparency using the example from here
- Get the alpha channel.
Use ImageDraw.floodfill for filling the surrounding zero alpha with 255
color.
(Only the eye stays black).
- Invert alpha - make the eye white instead of black.
- Paste the white eye on the image with the "transparent white".
Code sample (reading local image):
from PIL import Image, ImageDraw, ImageOps
import numpy as np
# https://stackoverflow.com/questions/765736/how-to-use-pil-to-make-all-white-pixels-transparent
def white_to_transparency(img):
x = np.asarray(img.convert('RGBA')).copy()
x[:, :, 3] &= (255 * (x[:, :, :3] != 255).any(axis=2)).astype(np.uint8) # Small modification: &= is used instead of = (in the original code).
return Image.fromarray(x)
filename = "68.png"
image = Image.open(filename)
im_white_transparent = white_to_transparency(image)
# https://stackoverflow.com/questions/63219166/advanced-cropping-with-python-imaging-library
# Extract alpha channel as new Image
alpha = im_white_transparent.getchannel('A')
# https://stackoverflow.com/questions/46083880/fill-in-a-hollow-shape-using-python-and-pillow-pil
# Fill alpha channel with 255, only the inner part stays 0
ImageDraw.floodfill(alpha, xy=(0, 0), value=255, thresh=200)
mask = ImageOps.invert(alpha) # Invert alpha - make the eye white instead of black
im_white_transparent.paste(image, (0, 0), mask) # Paste the white eye on the image with "transparent white".
# Show images for testing
im_white_transparent.show()
alpha.show()
mask.show()
Result:
im_white_transparent
:
(change to dark mode for seeing the transparent background):

Same result with transparency as chessboard pattern:

mask
:
