Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@radarhere
Copy link
Member

@radarhere radarhere commented Jun 23, 2021

This PR has several changes

  • the ImagePalette colors dictionary 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

@radarhere
Copy link
Member Author

radarhere commented Jun 27, 2021

I've pushed another commit to not use ImagePalette.raw in convert. Since this code -

Pillow/src/PIL/Image.py

Lines 1012 to 1019 in 52856bc

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)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using https://pypi.org/project/apng/ to split Tests/images/apng/mode_palette_alpha.png into frames, this matches the transparent third frame

im_cropped = im_expanded.crop(
(10, 10, im_expanded.width - 10, im_expanded.height - 10)
)
assert_image_equal(im_cropped, im)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expanding the test from #5551, bringing it closer to #5375

@radarhere
Copy link
Member Author

radarhere commented Jun 28, 2021

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.
out

And with the addition of that change, this PR now resolves #2803

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 this pull request may close these issues.

Exception when converting GIF to RGB and saving

2 participants