mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-27 17:54:32 +03:00
When allocating a new color, repurpose an unused index if necessary
This commit is contained in:
parent
f3451aefc6
commit
fa559277fb
|
@ -760,7 +760,7 @@ 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)
|
||||
background = im.palette.getcolor(background, im)
|
||||
return background
|
||||
|
||||
|
||||
|
|
|
@ -978,7 +978,7 @@ class Image:
|
|||
trns_im.putpalette(self.palette)
|
||||
if isinstance(t, tuple):
|
||||
try:
|
||||
t = trns_im.palette.getcolor(t)
|
||||
t = trns_im.palette.getcolor(t, self)
|
||||
except Exception as e:
|
||||
raise ValueError(
|
||||
"Couldn't allocate a palette color for transparency"
|
||||
|
@ -1016,7 +1016,7 @@ class Image:
|
|||
del new.info["transparency"]
|
||||
if trns is not None:
|
||||
try:
|
||||
new.info["transparency"] = new.palette.getcolor(trns)
|
||||
new.info["transparency"] = new.palette.getcolor(trns, new)
|
||||
except Exception:
|
||||
# if we can't make a transparent color, don't leave the old
|
||||
# transparency hanging around to mess us up.
|
||||
|
@ -1049,7 +1049,7 @@ class Image:
|
|||
if trns is not None:
|
||||
if new_im.mode == "P":
|
||||
try:
|
||||
new_im.info["transparency"] = new_im.palette.getcolor(trns)
|
||||
new_im.info["transparency"] = new_im.palette.getcolor(trns, new_im)
|
||||
except Exception:
|
||||
del new_im.info["transparency"]
|
||||
warnings.warn("Couldn't allocate palette entry for transparency")
|
||||
|
@ -1764,7 +1764,7 @@ class Image:
|
|||
and len(value) in [3, 4]
|
||||
):
|
||||
# RGB or RGBA value for a P image
|
||||
value = self.palette.getcolor(value)
|
||||
value = self.palette.getcolor(value, self)
|
||||
return self.im.putpixel(xy, value)
|
||||
|
||||
def remap_palette(self, dest_map, source_palette=None):
|
||||
|
|
|
@ -70,6 +70,7 @@ class ImageDraw:
|
|||
self.palette = im.palette
|
||||
else:
|
||||
self.palette = None
|
||||
self._image = im
|
||||
self.im = im.im
|
||||
self.draw = Image.core.draw(self.im, blend)
|
||||
self.mode = mode
|
||||
|
@ -108,13 +109,13 @@ class ImageDraw:
|
|||
if isinstance(ink, str):
|
||||
ink = ImageColor.getcolor(ink, self.mode)
|
||||
if self.palette and not isinstance(ink, numbers.Number):
|
||||
ink = self.palette.getcolor(ink)
|
||||
ink = self.palette.getcolor(ink, self._image)
|
||||
ink = self.draw.draw_ink(ink)
|
||||
if fill is not None:
|
||||
if isinstance(fill, str):
|
||||
fill = ImageColor.getcolor(fill, self.mode)
|
||||
if self.palette and not isinstance(fill, numbers.Number):
|
||||
fill = self.palette.getcolor(fill)
|
||||
fill = self.palette.getcolor(fill, self._image)
|
||||
fill = self.draw.draw_ink(fill)
|
||||
return ink, fill
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ class ImagePalette:
|
|||
# Declare tostring as an alias for tobytes
|
||||
tostring = tobytes
|
||||
|
||||
def getcolor(self, color):
|
||||
def getcolor(self, color, image=None):
|
||||
"""Given an rgb tuple, allocate palette entry.
|
||||
|
||||
.. warning:: This method is experimental.
|
||||
|
@ -118,6 +118,13 @@ class ImagePalette:
|
|||
if isinstance(self.palette, bytes):
|
||||
self._palette = bytearray(self.palette)
|
||||
index = len(self.palette) // 3
|
||||
if index >= 256:
|
||||
if image:
|
||||
# Search for an unused index
|
||||
for i, count in reversed(list(enumerate(image.histogram()))):
|
||||
if count == 0:
|
||||
index = i
|
||||
break
|
||||
if index >= 256:
|
||||
raise ValueError("cannot allocate more than 256 colors") from e
|
||||
self.colors[color] = index
|
||||
|
|
|
@ -54,6 +54,7 @@ class PyAccess:
|
|||
self.image32 = ffi.cast("int **", vals["image32"])
|
||||
self.image = ffi.cast("unsigned char **", vals["image"])
|
||||
self.xsize, self.ysize = img.im.size
|
||||
self._img = img
|
||||
|
||||
# Keep pointer to im object to prevent dereferencing.
|
||||
self._im = img.im
|
||||
|
@ -93,7 +94,7 @@ class PyAccess:
|
|||
and len(color) in [3, 4]
|
||||
):
|
||||
# RGB or RGBA value for a P image
|
||||
color = self._palette.getcolor(color)
|
||||
color = self._palette.getcolor(color, self._img)
|
||||
|
||||
return self.set_pixel(x, y, color)
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user