Converting PNG32 to PNG8 with PIL while preserving transparency

前端 未结 4 956
悲哀的现实
悲哀的现实 2020-12-16 04:48

I would like to convert a PNG32 image (with transparency) to PNG8 with Python Image Library. So far I have succeeded converting to PNG8 with a solid background.

Belo

相关标签:
4条回答
  • 2020-12-16 05:15

    Don't use PIL to generate the palette, as it can't handle RGBA properly and has quite limited quantization algorithm.

    Use pngquant instead.

    0 讨论(0)
  • 2020-12-16 05:17

    This is an old question so perhaps older answers are tuned to older version of PIL?

    But for anyone coming to this with Pillow>=6.0.0 then the following answer is many magnitudes faster and simpler.

    im = Image.open('png32_or_png64_with_alpha.png')
    im = im.quantize()
    im.save('png8_with_alpha_channel_preserved.png')
    
    0 讨论(0)
  • 2020-12-16 05:33

    As mentioned by Mark Ransom, your paletized image will only have one transparency level.

    When saving your paletized image, you'll have to specify which color index you want to be the transparent color like this :

    im.save("logo_py.png", transparency=0) 
    

    to save the image as a paletized colors and using the first color as a transparent color.

    0 讨论(0)
  • 2020-12-16 05:38

    After much searching on the net, here is the code to accomplish what I asked for:

    from PIL import Image
    
    im = Image.open("logo_256.png")
    
    # PIL complains if you don't load explicitly
    im.load()
    
    # Get the alpha band
    alpha = im.split()[-1]
    
    im = im.convert('RGB').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
    im.paste(255, mask)
    
    # The transparency index is 255
    im.save("logo_py.png", transparency=255)
    

    Source: http://nadiana.com/pil-tips-converting-png-gif Although the code there does not call im.load(), and thus crashes on my version of os/python/pil. (It looks like that is the bug in PIL).

    0 讨论(0)
提交回复
热议问题