Skip to content

Commit 2275993

Browse files
authored
When converting RGBA to PA, use RGB to P quantization (#9153)
2 parents b3d1836 + 762bdce commit 2275993

File tree

4 files changed

+34
-10
lines changed

4 files changed

+34
-10
lines changed

Tests/test_image.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,6 +1099,12 @@ def test_apply_transparency(self) -> None:
10991099
assert im.palette is not None
11001100
assert im.palette.colors[(27, 35, 6, 214)] == 24
11011101

1102+
def test_merge_pa(self) -> None:
1103+
p = hopper("P")
1104+
a = Image.new("L", p.size)
1105+
pa = Image.merge("PA", (p, a))
1106+
assert p.getpalette() == pa.getpalette()
1107+
11021108
def test_constants(self) -> None:
11031109
for enum in (
11041110
Image.Transpose,

Tests/test_image_convert.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,13 @@ def test_opaque() -> None:
9797
assert_image_equal(alpha, solid)
9898

9999

100+
def test_rgba() -> None:
101+
with Image.open("Tests/images/transparent.png") as im:
102+
assert im.mode == "RGBA"
103+
104+
assert_image_similar(im.convert("RGBa").convert("RGB"), im.convert("RGB"), 1.5)
105+
106+
100107
def test_rgba_p() -> None:
101108
im = hopper("RGBA")
102109
im.putalpha(hopper("L"))
@@ -107,6 +114,13 @@ def test_rgba_p() -> None:
107114
assert_image_similar(im, comparable, 20)
108115

109116

117+
def test_rgba_pa() -> None:
118+
im = hopper("RGBA").convert("PA").convert("RGB")
119+
expected = hopper("RGB")
120+
121+
assert_image_similar(im, expected, 9.3)
122+
123+
110124
def test_pa() -> None:
111125
im = hopper().convert("PA")
112126

@@ -115,13 +129,6 @@ def test_pa() -> None:
115129
assert palette.colors != {}
116130

117131

118-
def test_rgba() -> None:
119-
with Image.open("Tests/images/transparent.png") as im:
120-
assert im.mode == "RGBA"
121-
122-
assert_image_similar(im.convert("RGBa").convert("RGB"), im.convert("RGB"), 1.5)
123-
124-
125132
def test_trns_p(tmp_path: Path) -> None:
126133
im = hopper("P")
127134
im.info["transparency"] = 0

src/PIL/Image.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,8 +1009,14 @@ def convert_transparency(
10091009
new_im.info["transparency"] = transparency
10101010
return new_im
10111011

1012-
if mode == "P" and self.mode == "RGBA":
1013-
return self.quantize(colors)
1012+
if self.mode == "RGBA":
1013+
if mode == "P":
1014+
return self.quantize(colors)
1015+
elif mode == "PA":
1016+
r, g, b, a = self.split()
1017+
rgb = merge("RGB", (r, g, b))
1018+
p = rgb.quantize(colors)
1019+
return merge("PA", (p, a))
10141020

10151021
trns = None
10161022
delete_trns = False

src/_imaging.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2419,7 +2419,12 @@ _merge(PyObject *self, PyObject *args) {
24192419
bands[3] = band3->image;
24202420
}
24212421

2422-
return PyImagingNew(ImagingMerge(mode, bands));
2422+
Imaging imOut = ImagingMerge(mode, bands);
2423+
if (!imOut) {
2424+
return NULL;
2425+
}
2426+
ImagingCopyPalette(imOut, bands[0]);
2427+
return PyImagingNew(imOut);
24232428
}
24242429

24252430
static PyObject *

0 commit comments

Comments
 (0)