diff --git a/Tests/test_imageops.py b/Tests/test_imageops.py index 0b0bd1295..94370fa24 100644 --- a/Tests/test_imageops.py +++ b/Tests/test_imageops.py @@ -606,7 +606,7 @@ def test_autocontrast_preserve_one_color(color: tuple[int, int, int]) -> None: assert_image_equal(img, out) -def test_dither_primary_returns_image(): +def test_dither_primary_returns_image() -> None: im = Image.new("RGB", (4, 4), (128, 128, 128)) out = ImageOps.dither_primary(im) @@ -615,20 +615,25 @@ def test_dither_primary_returns_image(): assert out.mode == "RGB" -def test_dither_primary_uses_only_primary_colors(): +def test_dither_primary_uses_only_primary_colors() -> None: im = Image.new("RGB", (4, 4), (200, 100, 50)) out = ImageOps.dither_primary(im) - pixels = out.load() + px = out.load() + assert px is not None + for x in range(out.width): for y in range(out.height): - r, g, b = pixels[x, y] + value = px[x, y] + assert isinstance(value, tuple) + + r, g, b = value assert r in (0, 255) assert g in (0, 255) assert b in (0, 255) -def test_dither_primary_small_image(): +def test_dither_primary_small_image() -> None: im = Image.new("RGB", (2, 2), (255, 0, 0)) out = ImageOps.dither_primary(im) diff --git a/src/PIL/ImageOps.py b/src/PIL/ImageOps.py index 001d7629c..3e692abd1 100644 --- a/src/PIL/ImageOps.py +++ b/src/PIL/ImageOps.py @@ -675,9 +675,12 @@ def dither_primary(image: Image.Image) -> Image.Image: dst = out.load() # Step 1: primary color reduction + assert src is not None for x in range(width): for y in range(height): - r, g, b = src[x, y] + px = src[x, y] + assert isinstance(px, tuple) + r, g, b = px src[x, y] = ( 255 if r > 127 else 0, 255 if g > 127 else 0, @@ -685,6 +688,7 @@ def dither_primary(image: Image.Image) -> Image.Image: ) # Step 2: ordered dithering (2x2 blocks) + assert dst is not None for x in range(0, width - 1, 2): for y in range(0, height - 1, 2): p1 = src[x, y] @@ -692,18 +696,22 @@ def dither_primary(image: Image.Image) -> Image.Image: p3 = src[x + 1, y] p4 = src[x + 1, y + 1] + assert isinstance(p1, tuple) + assert isinstance(p2, tuple) + assert isinstance(p3, tuple) + assert isinstance(p4, tuple) red = (p1[0] + p2[0] + p3[0] + p4[0]) / 4 green = (p1[1] + p2[1] + p3[1] + p4[1]) / 4 blue = (p1[2] + p2[2] + p3[2] + p4[2]) / 4 - r = [_dither_saturation(red, q) for q in range(4)] - g = [_dither_saturation(green, q) for q in range(4)] - b = [_dither_saturation(blue, q) for q in range(4)] + r1 = [_dither_saturation(red, q) for q in range(4)] + g1 = [_dither_saturation(green, q) for q in range(4)] + b1 = [_dither_saturation(blue, q) for q in range(4)] - dst[x, y] = (r[0], g[0], b[0]) - dst[x, y + 1] = (r[1], g[1], b[1]) - dst[x + 1, y] = (r[2], g[2], b[2]) - dst[x + 1, y + 1] = (r[3], g[3], b[3]) + dst[x, y] = (r1[0], g1[0], b1[0]) + dst[x, y + 1] = (r1[1], g1[1], b1[1]) + dst[x + 1, y] = (r1[2], g1[2], b1[2]) + dst[x + 1, y + 1] = (r1[3], g1[3], b1[3]) return out