Convert PNG32 to PNG8 with PIL while maintaining transparency

I would like to convert a PNG32 image (with transparency) to PNG8 using the Python image library. So far, I have managed to convert PNG8 with a solid background.

Below I do:

from PIL import Image im = Image.open("logo_256.png") im = im.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=255) im.save("logo_py.png", colors=255) 
+6
source share
3 answers

After a lot of searching on the net, here is the code for doing what I requested:

 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 does not call im.load () there, and thus it crashes in my version of os / python / pil. (This seems to be a bug in the PIL).

+12
source

As mentioned by Mark Ransom, your palette will only have one level of transparency.

When saving a palette, you need to specify which color index you want to be transparent, for example:

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

to save the image as palitic colors and use the first color as a transparent color.

+1
source

Do not use PIL to create a palette, as it cannot control RGBA correctly and has a rather limited quantization algorithm.

Use pngquant .

+1
source

Source: https://habr.com/ru/post/888938/


All Articles