Skip to content

Instantly share code, notes, and snippets.

@vietlq
Last active May 1, 2017 17:18
Show Gist options
  • Save vietlq/475f156b0fef3eae337dffa0eb04441a to your computer and use it in GitHub Desktop.
Save vietlq/475f156b0fef3eae337dffa0eb04441a to your computer and use it in GitHub Desktop.
PySmile Transparency Preservation: Implementation Details
def alpha_to_color(image, color=(255, 255, 255)):
"""Set all fully transparent pixels of an RGBA image to the specified color.
This is a very simple solution that might leave over some ugly edges, due
to semi-transparent areas. You should use alpha_composite_with color instead.
Source: http://stackoverflow.com/a/9166671/284318
Keyword Arguments:
image -- PIL RGBA Image object
color -- Tuple r, g, b (default 255, 255, 255)
Remember to convert to RGB before saving to non-RGBA formats:
new_im = im.convert('RGB')
"""
x = np.array(image)
r, g, b, a = np.rollaxis(x, axis=-1)
r[a == 0] = color[0]
g[a == 0] = color[1]
b[a == 0] = color[2]
x = np.dstack([r, g, b, a])
return Image.fromarray(x, 'RGBA')
def convert_to_palette(image):
"""Convert transparent image to GIF
Reference: http://www.pythonclub.org/modules/pil/convert-png-gif
"""
# Needed for split()
image.load()
# Get the alpha band
alpha = image.split()[3]
# To have best quality, have non-destructive RGBA to RGB conversion first
background = pure_pil_alpha_to_color_v2(image)
# Convert to palette format
background = background.convert('P', palette=Image.ADAPTIVE, colors=255)
# Set all pixel values below 128 to 255, and the rest to 0
mask = Image.eval(alpha, lambda a: 255 if a <= 128 else 0)
# Paste the color of index 255 and use alpha as a mask
background.paste(255, mask)
return background
def pure_pil_alpha_to_color_v2(image, color=(255, 255, 255)):
"""Alpha composite an RGBA Image with a specified color.
Simpler, faster version than the solutions above.
Source: http://stackoverflow.com/a/9459208/284318
Keyword Arguments:
image -- PIL RGBA Image object
color -- Tuple r, g, b (default 255, 255, 255)
"""
image.load() # needed for split()
background = Image.new('RGB', image.size, color)
background.paste(image, mask=image.split()[3]) # 3 is the alpha channel
return background
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment