diff --git a/Tests/test_image_transform.py b/Tests/test_image_transform.py index 12a05ec18b1..298ffe527e4 100644 --- a/Tests/test_image_transform.py +++ b/Tests/test_image_transform.py @@ -94,7 +94,7 @@ def test_quad(self) -> None: ( ("RGB", (255, 0, 0)), ("RGBA", (255, 0, 0, 255)), - ("LA", (76, 0)), + ("LA", (76, 255)), ), ) def test_fill(self, mode: str, expected_pixel: tuple[int, ...]) -> None: diff --git a/Tests/test_imagecolor.py b/Tests/test_imagecolor.py index 6eea7886dd8..2b191521613 100644 --- a/Tests/test_imagecolor.py +++ b/Tests/test_imagecolor.py @@ -199,6 +199,18 @@ def test_color_hsv() -> None: assert (170, 255, 255) == ImageColor.getcolor("hsv(240, 100%, 100%)", "HSV") +@pytest.mark.parametrize("mode, premultiplied_mode", (("LA", "La"), ("RGBA", "RGBa"))) +@pytest.mark.parametrize("color", ("#f00", "#ff000080", "#ff000050")) +def test_color_premultiplied_alpha( + mode: str, premultiplied_mode: str, color: str +) -> None: + im = Image.new(mode, (1, 1), color) + im_premultiplied = im.convert(premultiplied_mode) + expected = im_premultiplied.getpixel((0, 0)) + + assert ImageColor.getcolor(color, premultiplied_mode) == expected + + def test_color_too_long() -> None: # Arrange color_too_long = "hsl(" + "1" * 40 + "," + "1" * 40 + "%," + "1" * 40 + "%)" diff --git a/src/PIL/ImageColor.py b/src/PIL/ImageColor.py index 9a15a8eb759..ef1548c7e23 100644 --- a/src/PIL/ImageColor.py +++ b/src/PIL/ImageColor.py @@ -152,17 +152,19 @@ def getcolor(color: str, mode: str) -> int | tuple[int, ...]: r, g, b = rgb h, s, v = rgb_to_hsv(r / 255, g / 255, b / 255) return int(h * 255), int(s * 255), int(v * 255) - elif Image.getmodebase(mode) == "L": + if Image.getmodebase(mode) == "L": r, g, b = rgb # ITU-R Recommendation 601-2 for nonlinear RGB # scaled to 24 bits to match the convert's implementation. graylevel = (r * 19595 + g * 38470 + b * 7471 + 0x8000) >> 16 - if mode[-1] == "A": - return graylevel, alpha - return graylevel - elif mode[-1] == "A": - return rgb + (alpha,) - return rgb + value: tuple[int, ...] = (graylevel,) + else: + value = rgb + if mode[-1] == "a": + value = tuple(round(band * alpha / 255) for band in value) + if mode[-1] in ("A", "a"): + return value + (alpha,) + return value[0] if len(value) == 1 else value colormap: dict[str, str | tuple[int, int, int]] = {