How to Use Pil to Make All White Pixels Transparent

How to use PIL to make all white pixels transparent?

You need to make the following changes:

  • append a tuple (255, 255, 255, 0) and not a list [255, 255, 255, 0]
  • use img.putdata(newData)

This is the working code:

from PIL import Image

img = Image.open('img.png')
img = img.convert("RGBA")
datas = img.getdata()

newData = []
for item in datas:
if item[0] == 255 and item[1] == 255 and item[2] == 255:
newData.append((255, 255, 255, 0))
else:
newData.append(item)

img.putdata(newData)
img.save("img2.png", "PNG")

Create transparent background for white png image Python

You can try to subtract from the white pixels to make it grey like

from PIL import Image
import numpy as np

img = Image.open('your_image.png')
np_img = np.array(img)
v = 50 # the more v, the more black
np_img = np_img - [v,v,v,0] #[R, G, B, alpha]
np_img[np_img<0] = 0 # make the negative values to 0

Image.fromarray(np_img.astype('uint8'))

If you want to change the background

from PIL import Image
import numpy as np

img = Image.open('t2.png')
np_img = np.array(img)

bg = np.ones_like(np_img)
bg[:] = [255,0,0,255] # red
bg[:] = [0,255,0,255] # green
bg[:] = [0,0,255,255] # blue
bg[:] = [125,125,125,255] # gray

bg[np_img>0] = 0

np_img = bg + np_img

Image.fromarray(np_img.astype('uint8'))

Why PIL convert('RGB') makes some transparent into black but some into white?

Both images have transparency in them, it's just that one has white pixels made transparent and the other has black pixels made transparent. Another way of saying the same thing is that the underlying colour of transparent pixels is black in one image and white in the other. You can't see the difference because they are transparent!

Here is lenna1 with the alpha layer removed on the left, then the alpha layer itself on the right:

Sample Image

And here is lenna2 with the alpha layer removed on the left, then the alpha layer itself on the right:

Sample Image

You can make them the same by finding all the transparent pixels, and making them white like this:

# Load the image and make into Numpy array
rgba = np.array(Image.open('lena2.png'))

# Make image transparent white anywhere it is transparent
rgba[rgba[...,-1]==0] = [255,255,255,0]

# Make back into PIL Image and save
Image.fromarray(rgba).save('result.png')

If you want to make the transparent pixels visible blue so you can see them for testing, use:

rgba[rgba[...,-1]==0] = [0,0,255,255]

If you have ImageMagick installed, you can force all transparent pixels to become the colour of your choice, say magenta, in Terminal:

magick lenna1.png -background magenta -alpha background result.png

That often means you can improve PNG compression and decrease PNG file sizes by making all transparent pixels black and, as a result, the image is likely to compress much better than if the transparent pixels are all wildly different colours:

magick image.png -background black -alpha background result.png

Remove border from Logo using Python PIL

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):

Sample Image

Same result with transparency as chessboard pattern:

Sample Image

mask:

Sample Image

How can I set the background of a transparent image to white, using PIL?

import Image
from resizeimage import resizeimage

f = Image.open('old.png')
alpha1 = 0 # Original value
r2, g2, b2, alpha2 = 255, 255, 255,255 # Value that we want to replace it with

red, green, blue,alpha = data[:,:,0], data[:,:,1], data[:,:,2], data[:,:,3]
mask = (alpha==alpha1)
data[:,:,:3][mask] = [r2, g2, b2, alpha2]

data = np.array(f)
f = Image.fromarray(data)
f = f.resize((basewidth,hsize), PIL.Image.ANTIALIAS)

f.save('modified.png', image.format)


Related Topics



Leave a reply



Submit