From f8ead6623429dda64fb4e9e4b523d864d007d23c Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Wed, 7 Oct 2026 23:20:23 +1100 Subject: [PATCH 1/2] Mark Python palette as dirty after conversion to WEB palette --- Tests/test_image_convert.py | 2 +- src/PIL/Image.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/test_image_convert.py b/Tests/test_image_convert.py index f596f009025..c0dbb4fabaa 100644 --- a/Tests/test_image_convert.py +++ b/Tests/test_image_convert.py @@ -293,7 +293,7 @@ def test_p2pa_alpha() -> None: def test_p2pa_palette() -> None: with Image.open("Tests/images/tiny.png") as im: im_pa = im.convert("PA") - assert im_pa.getpalette() == im.getpalette() + assert im_pa.getpalette(None) == im.getpalette() rgb2xyz_matrix = ( diff --git a/src/PIL/Image.py b/src/PIL/Image.py index daec86c5404..340d726b1ba 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -1252,7 +1252,7 @@ def convert_transparency( if mode in ("P", "PA") and palette != Palette.ADAPTIVE: from . import ImagePalette - new_im.palette = ImagePalette.ImagePalette("RGB", im.getpalette("RGB")) + new_im.palette = ImagePalette.raw("RGB", im.getpalette("RGB")) if delete_trns: # crash fail if we leave a bytes transparency in an rgb/l mode. del new_im.info["transparency"] From b850abad4865a2756cbf930784953b3fe9810cad Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Wed, 7 Oct 2026 23:29:44 +1100 Subject: [PATCH 2/2] Load new palette in putpalette() if core image was L or LA --- Tests/test_image_putpalette.py | 2 +- src/PIL/Image.py | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Tests/test_image_putpalette.py b/Tests/test_image_putpalette.py index 6b89807db34..8b3e2c53a95 100644 --- a/Tests/test_image_putpalette.py +++ b/Tests/test_image_putpalette.py @@ -12,7 +12,7 @@ def palette(mode: str) -> str | tuple[str, list[int]]: im = hopper(mode).copy() im.putpalette(list(range(256)) * 3) assert im.palette is not None - assert im.palette.dirty + assert im.palette.dirty == (0 if mode[0] == "L" else 1) p = im.getpalette() if p: diff --git a/src/PIL/Image.py b/src/PIL/Image.py index 340d726b1ba..57b2287b9e1 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -2175,8 +2175,12 @@ def putpalette( self.palette.mode = "RGBA" if self.palette.mode == self.palette.rawmode: self.palette.rawmode = None - if self.palette.rawmode: - self.load() # decode raw palette data + if self.palette.rawmode or ( + self._im is not None and self._im.mode != self.mode + ): + # either raw palette data needs to be decoded, + # or the core image needs its mode updated + self.load() def putpixel( self,