When converting RGBA to PA, use RGB to P quantization (#9153)

This commit is contained in:
Andrew Murray 2025-10-05 06:10:59 +11:00 committed by GitHub
commit 2275993541
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 34 additions and 10 deletions

View File

@ -1099,6 +1099,12 @@ class TestImage:
assert im.palette is not None assert im.palette is not None
assert im.palette.colors[(27, 35, 6, 214)] == 24 assert im.palette.colors[(27, 35, 6, 214)] == 24
def test_merge_pa(self) -> None:
p = hopper("P")
a = Image.new("L", p.size)
pa = Image.merge("PA", (p, a))
assert p.getpalette() == pa.getpalette()
def test_constants(self) -> None: def test_constants(self) -> None:
for enum in ( for enum in (
Image.Transpose, Image.Transpose,

View File

@ -97,6 +97,13 @@ def test_opaque() -> None:
assert_image_equal(alpha, solid) assert_image_equal(alpha, solid)
def test_rgba() -> None:
with Image.open("Tests/images/transparent.png") as im:
assert im.mode == "RGBA"
assert_image_similar(im.convert("RGBa").convert("RGB"), im.convert("RGB"), 1.5)
def test_rgba_p() -> None: def test_rgba_p() -> None:
im = hopper("RGBA") im = hopper("RGBA")
im.putalpha(hopper("L")) im.putalpha(hopper("L"))
@ -107,6 +114,13 @@ def test_rgba_p() -> None:
assert_image_similar(im, comparable, 20) assert_image_similar(im, comparable, 20)
def test_rgba_pa() -> None:
im = hopper("RGBA").convert("PA").convert("RGB")
expected = hopper("RGB")
assert_image_similar(im, expected, 9.3)
def test_pa() -> None: def test_pa() -> None:
im = hopper().convert("PA") im = hopper().convert("PA")
@ -115,13 +129,6 @@ def test_pa() -> None:
assert palette.colors != {} assert palette.colors != {}
def test_rgba() -> None:
with Image.open("Tests/images/transparent.png") as im:
assert im.mode == "RGBA"
assert_image_similar(im.convert("RGBa").convert("RGB"), im.convert("RGB"), 1.5)
def test_trns_p(tmp_path: Path) -> None: def test_trns_p(tmp_path: Path) -> None:
im = hopper("P") im = hopper("P")
im.info["transparency"] = 0 im.info["transparency"] = 0

View File

@ -1009,8 +1009,14 @@ class Image:
new_im.info["transparency"] = transparency new_im.info["transparency"] = transparency
return new_im return new_im
if mode == "P" and self.mode == "RGBA": if self.mode == "RGBA":
return self.quantize(colors) if mode == "P":
return self.quantize(colors)
elif mode == "PA":
r, g, b, a = self.split()
rgb = merge("RGB", (r, g, b))
p = rgb.quantize(colors)
return merge("PA", (p, a))
trns = None trns = None
delete_trns = False delete_trns = False

View File

@ -2419,7 +2419,12 @@ _merge(PyObject *self, PyObject *args) {
bands[3] = band3->image; bands[3] = band3->image;
} }
return PyImagingNew(ImagingMerge(mode, bands)); Imaging imOut = ImagingMerge(mode, bands);
if (!imOut) {
return NULL;
}
ImagingCopyPalette(imOut, bands[0]);
return PyImagingNew(imOut);
} }
static PyObject * static PyObject *