Python: Make transparent areas in PIL image to white (or any other solid opaque colour)

2 Comments

I had some issues with transparent PNG images causing some strange effects when resized and saved with Python's PIL Image library.

image image

image image

As you can see, those jarring effects are hard to ignore.

The issue was I was ignoring the alpha channel during conversion and PIL didn't quite know what to do with it.

from PIL import Image
image = Image.open("some_file.png")
image.convert("RGBA") # Convert this to RGBA if possible
canvas = PyImage.new('RGBA', image.size, (255,255,255,255)) # Empty canvas colour (r,g,b,a)
canvas.paste(image, mask=image) # Paste the image onto the canvas, using it's alpha channel as mask
canvas.thumbnail([width, height], PyImage.ANTIALIAS)
canvas.save(filename, format="PNG")
view raw gistfile1.py hosted with ❤ by GitHub

It is a bit more work, but the results speak for themselves. Even the GIF image quality was improved after using this method!

image image
You'll have top view them at 100% to see the difference.

Update 6/12/14:

I found a better way of colouring the images which had NO loss in quality (updated code above)

345_shirt_438cef451b28326350794f77d38fe83d_B 345_shirt_438cef451b28326350794f77d38fe83d

(Shirt design "Majin Power!" by ddjvigo)

You can easily see which one is rendered with the new code as the difference is quite noticeable.

There was a bug which replaced the whole pixel with white, which is wrong because it could be any other colour with transparency < 255.

(Here's the old code if anyone was wondering)

image = Image.open("some_file.png")
image.convert("RGBA") # Convert this to RGBA if possible
pixel_data = image.load()
if image.mode == "RGBA":
# If the image has an alpha channel, convert it to white
# Otherwise we'll get weird pixels
for y in xrange(image.size[1]): # For each row ...
for x in xrange(image.size[0]): # Iterate through each column ...
# Check if it's opaque
if pixel_data[x, y][3] < 255:
# Replace the pixel data with the colour white
pixel_data[x, y] = (255, 255, 255, 255)
# Resize the image thumbnail
image.thumbnail([resolution.width, resolution.height], Image.ANTIALIAS)
image.save(filename)
view raw gistfile1.py hosted with ❤ by GitHub

Sources

 
Copyright © Twig's Tech Tips
Theme by BloggerThemes & TopWPThemes Sponsored by iBlogtoBlog