Resizing png image with PIL loses transparency

python, python-imaging-library

Solution

The problem is unrelated to the linked question, instead you have to patch PIL such that it reads the `tRNS` PNG chunk correctly. PIL assumes a single value for this chunk, but this image shown has a transparency description for each value in the palette. After that is handled, then it is simple to solve the problem: convert the image to the `'LA'` mode and resize:

import sys
from PIL import Image

img = Image.open(sys.argv[1])
pal = img.getpalette()
width, height = img.size
actual_transp = img.info['actual_transparency'] # XXX This will fail.

result = Image.new('LA', img.size)

im = img.load()
res = result.load()
for x in range(width):
    for y in range(height):
        t = actual_transp[im[x, y]]
        color = pal[im[x, y]]
        res[x, y] = (color, t)

result.resize((64, 64), Image.ANTIALIAS).save(sys.argv[2])

So we go from this , to this:

The PIL patch for this specific situation is very simple actually. Open your `PIL/PngImagePlugin.py`, go to the function `chunk_tRNS`, enter the `if` statement that checks for `im_mode == "P"` and the subsequent check for `i >= 0`, then add the line `self.im_info["actual_transparency"] = map(ord, s)`.

Problem

I use this method to resize png images: Method for converting PNGs to premultiplied alpha But this image still loses transparency: ``` import Image, numpy def resize(filename, img,height, width): if filename.endswith(".png"): img = img.convert('RGBA') premult = numpy.fromstring(img.tostring(), dtype=numpy.uint8) alphaLayer = premult[3::4] / 255.0 premult[::4] *= alphaLayer premult[1::4] *= alphaLayer premult[2::4] *= alphaLayer img = Image.fromstring("RGBA", img.size, premult.tostring()) img = img.resize((height,width), Image.ANTIALIAS) return img ``` from to

Original source

Related problems