If all 256 colors are in use, then there is no need for an additional color for background or transparency

This commit is contained in:
Andrew Murray 2021-06-23 19:28:46 +10:00
parent fa559277fb
commit 8210645e4b
3 changed files with 39 additions and 15 deletions

View File

@ -31,8 +31,11 @@ def test_getcolor():
assert palette.getcolor((0, 0, 0)) == palette.getcolor((0, 0, 0, 255))
# An error is raised when the palette is full
with pytest.raises(ValueError):
palette.getcolor((1, 2, 3))
# But not if the image is not using one of the palette entries
palette.getcolor((1, 2, 3), image=Image.new("P", (1, 1)))
# Test unknown color specifier
with pytest.raises(ValueError):

View File

@ -760,7 +760,15 @@ def _get_background(im, infoBackground):
# WebPImagePlugin stores an RGBA value in info["background"]
# So it must be converted to the same format as GifImagePlugin's
# info["background"] - a global color table index
background = im.palette.getcolor(background, im)
try:
background = im.palette.getcolor(background, im)
except ValueError as e:
if str(e) == "cannot allocate more than 256 colors":
# If all 256 colors are in use,
# then there is no need for the background color
return 0
else:
raise
return background

View File

@ -979,19 +979,27 @@ class Image:
if isinstance(t, tuple):
try:
t = trns_im.palette.getcolor(t, self)
except Exception as e:
raise ValueError(
"Couldn't allocate a palette color for transparency"
) from e
trns_im.putpixel((0, 0), t)
if mode in ("L", "RGB"):
trns_im = trns_im.convert(mode)
except ValueError as e:
if str(e) == "cannot allocate more than 256 colors":
# If all 256 colors are in use,
# then there is no need for transparency
t = None
else:
raise ValueError(
"Couldn't allocate a palette color for transparency"
) from e
if t is None:
trns = None
else:
# can't just retrieve the palette number, got to do it
# after quantization.
trns_im = trns_im.convert("RGB")
trns = trns_im.getpixel((0, 0))
trns_im.putpixel((0, 0), t)
if mode in ("L", "RGB"):
trns_im = trns_im.convert(mode)
else:
# can't just retrieve the palette number, got to do it
# after quantization.
trns_im = trns_im.convert("RGB")
trns = trns_im.getpixel((0, 0))
elif self.mode == "P" and mode == "RGBA":
t = self.info["transparency"]
@ -1050,9 +1058,14 @@ class Image:
if new_im.mode == "P":
try:
new_im.info["transparency"] = new_im.palette.getcolor(trns, new_im)
except Exception:
except ValueError as e:
del new_im.info["transparency"]
warnings.warn("Couldn't allocate palette entry for transparency")
if str(e) != "cannot allocate more than 256 colors":
# If all 256 colors are in use,
# then there is no need for transparency
warnings.warn(
"Couldn't allocate palette entry for transparency"
)
else:
new_im.info["transparency"] = trns
return new_im