Support saving images with non-RGB palettes as PNGs

This commit is contained in:
Andrew Murray 2026-03-16 22:12:58 +11:00
parent 6a06285bf8
commit 8442a8541c
2 changed files with 15 additions and 2 deletions

View File

@ -707,6 +707,16 @@ class TestFilePng:
assert reloaded.png.im_palette is not None
assert len(reloaded.png.im_palette[1]) == 3
def test_plte_cmyk(self, tmp_path: Path) -> None:
im = Image.new("P", (1, 1))
im.putpalette((0, 100, 150, 200), "CMYK")
out = tmp_path / "temp.png"
im.save(out)
with Image.open(out) as reloaded:
assert reloaded.convert("CMYK").getpixel((0, 0)) == (200, 222, 232, 0)
def test_getxmp(self) -> None:
with Image.open("Tests/images/color_snakes.png") as im:
if ElementTree is None:

View File

@ -1353,6 +1353,9 @@ def _save(
mode = im.mode
outmode = mode
palette = []
if im.palette:
palette = im.getpalette() or []
if mode == "P":
#
# attempt to minimize storage requirements for palette images
@ -1362,7 +1365,7 @@ def _save(
else:
# check palette contents
if im.palette:
colors = max(min(len(im.palette.getdata()[1]) // 3, 256), 1)
colors = max(min(len(palette) // 3, 256), 1)
else:
colors = 256
@ -1435,7 +1438,7 @@ def _save(
if im.mode == "P":
palette_byte_number = colors * 3
palette_bytes = im.im.getpalette("RGB")[:palette_byte_number]
palette_bytes = bytes(palette[:palette_byte_number])
while len(palette_bytes) < palette_byte_number:
palette_bytes += b"\0"
chunk(fp, b"PLTE", palette_bytes)