Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pillow is saving unnecessary values in paletted pngs #5877

Closed
klaucos opened this issue Dec 8, 2021 · 1 comment · Fixed by #5879
Closed

Pillow is saving unnecessary values in paletted pngs #5877

klaucos opened this issue Dec 8, 2021 · 1 comment · Fixed by #5879
Labels

Comments

@klaucos
Copy link

klaucos commented Dec 8, 2021

Pillow is currently saving unnecessarily long palette information even in case we are saving just 2color png.

What did you do?

Pillow is saving all 256 colors in palette even if only 2 colors are defined thus increasing the size of the pngs significantly.
We use paletted pngs to save space and bandwidth but we have to manually remove palette from all pngs saved by Pillow. (In old version we would simply remove img.palette.palette altogether and png would be saved properly. In new versions it's no longer possible so we have to cut it to correct size)
Python code provided should show exact way how palettes are being increased in size by this issue.

What did you expect to happen?

I'd expect that output png would save only palette required. (2colors instead of 256colors)

What actually happened?

Pillow keeps saving unnecessary data that increases size of the paletted output pngs.

What are your OS, Python and Pillow versions?

  • OS: Ubuntu 20
  • Python: 3.9.1
  • Pillow: Pillow==8.4.0
from PIL import Image, ImageDraw

img = Image.new("RGB", (64, 64), (255,255,255))
# get a drawing context
draw = ImageDraw.Draw(img)
draw.line((0, 0) + img.size, fill=(0,255,0))
img.save('line.png', "PNG")  # Size 354 bytes
palette_img = img.quantize(colors=2)
palette_img.save('line_palette.png', "PNG")  # Size 878 bytes
# Saving with adaptive and optimize doesn't solve bloated png output:
pil_adaptive = img.convert("P", palette=Image.ADAPTIVE, colors=2)
pil_adaptive.save('line_palette_adaptive.png', "PNG", optimize=True)  # Size 878 bytes
# Remove all unneeded balast from pallete output, keeping only 6 bytes needed
# for pallete. (2x 3 rgb values)
palette_img.palette.palette = palette_img.palette.palette[:6]
palette_img.save('line_palette_no_balast.png', "PNG")  # Size 113 bytes
@radarhere
Copy link
Member

I've created PR #5879 to resolve this. Please try it and let us know if that's not what you're after.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants