使用PIL调整png图像大小会失去透明度

zur*_*roc 5 python python-imaging-library

我用这个方法来调整png图像的大小:

将PNG转换为预乘alpha的方法

但这张图片仍然失去透明度:

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
Run Code Online (Sandbox Code Playgroud)

http://i.stack.imgur.com/oPV5q.pnghttp://i.stack.imgur.com/jzmT9.png

mmg*_*mgp 3

该问题与链接的问题无关,相反,您必须修补 PIL,以便它tRNS正确读取 PNG 块。PIL 假定该块有一个值,但显示的此图像对调色板中的每个值都有透明度描述。处理完之后,解决问题就很简单了:将图像转换为模式'LA'并调整大小:

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])
Run Code Online (Sandbox Code Playgroud)

所以我们从这里开始在此输入图像描述,对此:在此输入图像描述

针对这种特定情况的 PIL 补丁实际上非常简单。打开您的PIL/PngImagePlugin.py函数,进入该函数chunk_tRNS,输入if检查的语句im_mode == "P"和后续的检查i >= 0,然后添加该行self.im_info["actual_transparency"] = map(ord, s)