Improved ImagePalette by radarhere · Pull Request #5552 · python-pillow/Pillow
This PR has several changes
- the ImagePalette
colorsdictionary is currently empty when the object is created, rather than being filled with palette entries. This fixes that - it changes the palette to be empty by default. This means that new colors can be appended more easily, rather than finding that all 256 entries are already occupied
- if a new color is added when 256 entries are taken, search through the image. If there is a palette index that isn't actually used, use that for the new color
- helps ImageOps.expand distorts image and converts png to grayscale #5375 by determining the border palette index on the new image only after the palette has been attached
Edit: Thanks to later commits, resolves #2803
I've pushed another commit to not use ImagePalette.raw in convert. Since this code -
| new.palette = ImagePalette.raw("RGB", new.im.getpalette("RGB")) | |
| if delete_trns: | |
| # This could possibly happen if we requantize to fewer colors. | |
| # The transparency would be totally off in that case. | |
| del new.info["transparency"] | |
| if trns is not None: | |
| try: | |
| new.info["transparency"] = new.palette.getcolor(trns) |
is currently always going to raise a ValueError.
| def raw(rawmode, data): | |
| palette = ImagePalette() | |
| palette.rawmode = rawmode |
| def getcolor(self, color): | |
| """Given an rgb tuple, allocate palette entry. | |
| .. warning:: This method is experimental. | |
| """ | |
| if self.rawmode: | |
| raise ValueError("palette contains raw palette data") |
This fixes the UserWarning in #2803
| assert im.getpixel((0, 0)) == (0, 255, 0, 255) | ||
| assert im.getpixel((64, 32)) == (0, 255, 0, 255) | ||
| assert im.getpixel((0, 0)) == (255, 0, 0, 0) | ||
| assert im.getpixel((64, 32)) == (255, 0, 0, 0) |
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| im_cropped = im_expanded.crop( | ||
| (10, 10, im_expanded.width - 10, im_expanded.height - 10) | ||
| ) | ||
| assert_image_equal(im_cropped, im) |
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've now pushed a commit, 'Fixed reloading palette'. It allows this code to work.
from PIL import Image im = Image.open("Tests/images/hopper.gif") im.load() im.palette.dirty = 1 im.save("out.png")
In master at the moment, it produces this broken output.

And with the addition of that change, this PR now resolves #2803
This was referenced
Jun 29, 2021This was referenced
Jul 26, 2021This was referenced
Oct 4, 2022This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters