diff --git a/Tests/test_image_quantize.py b/Tests/test_image_quantize.py index af4172c8808..1ceff084272 100644 --- a/Tests/test_image_quantize.py +++ b/Tests/test_image_quantize.py @@ -74,3 +74,13 @@ def test_quantize_dither_diff(): nodither = image.quantize(dither=0, palette=palette) assert dither.tobytes() != nodither.tobytes() + + +def test_transparent_colors_equal(): + im = Image.new("RGBA", (1, 2), (0, 0, 0, 0)) + px = im.load() + px[0, 1] = (255, 255, 255, 0) + + converted = im.quantize() + converted_px = converted.load() + assert converted_px[0, 0] == converted_px[0, 1] diff --git a/src/libImaging/Quant.c b/src/libImaging/Quant.c index f5a5d567c4e..8ec99699f06 100644 --- a/src/libImaging/Quant.c +++ b/src/libImaging/Quant.c @@ -1683,9 +1683,26 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans) { } else if (!strcmp(im->mode, "RGB") || !strcmp(im->mode, "RGBA")) { /* true colour */ + withAlpha = !strcmp(im->mode, "RGBA"); + int transparency = 0; + unsigned char r, g, b; for (i = y = 0; y < im->ysize; y++) { for (x = 0; x < im->xsize; x++, i++) { p[i].v = im->image32[y][x]; + if (withAlpha && p[i].c.a == 0) { + if (transparency == 0) { + transparency = 1; + r = p[i].c.r; + g = p[i].c.g; + b = p[i].c.b; + } else { + /* Set all subsequent transparent pixels + to the same colour as the first */ + p[i].c.r = r; + p[i].c.g = g; + p[i].c.b = b; + } + } } } @@ -1720,9 +1737,6 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans) { kmeans); break; case 2: - if (!strcmp(im->mode, "RGBA")) { - withAlpha = 1; - } result = quantize_octree( p, im->xsize * im->ysize, @@ -1734,9 +1748,6 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans) { break; case 3: #ifdef HAVE_LIBIMAGEQUANT - if (!strcmp(im->mode, "RGBA")) { - withAlpha = 1; - } result = quantize_pngquant( p, im->xsize,