From 9b9276849b3bb9b57900f21f90e98e6f330536ef Mon Sep 17 00:00:00 2001 From: James O'Leary Date: Thu, 11 Mar 2021 13:43:20 -0500 Subject: [PATCH] Ignore transparent pixels during WSMeans The WSMeans quantizer uses starting clusters from a Wu quantizer as starting points for an optimized Kmeans algorithm. The first thing the quantizer does is assign pixels from the image being quantized to those starting clusters. Either due to the image source or downscaling, transparent pixels may be in the pixels. Filter those out: they create misleading results, such as there being two colors in the image, semi-transparent black and green, in a wallpaper that is solid green by all accounts. Fixes: 182333325 Test: atest CtsAppTestCases:android.app.cts.WallpaperColorsTest#fromDrawableTest passes locally on sunfish. link: http://ab/I26300007868608112 Change-Id: Icaebd98eeba27d3dc59a698282dd3be03fce1bf9 --- .../internal/graphics/palette/WSMeansQuantizer.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/core/java/com/android/internal/graphics/palette/WSMeansQuantizer.java b/core/java/com/android/internal/graphics/palette/WSMeansQuantizer.java index b7c03d6a0b0ab..b4f216ba87fa6 100644 --- a/core/java/com/android/internal/graphics/palette/WSMeansQuantizer.java +++ b/core/java/com/android/internal/graphics/palette/WSMeansQuantizer.java @@ -68,6 +68,17 @@ public class WSMeansQuantizer implements Quantizer { } for (int pixel : pixels) { + // These are pixels from the bitmap that is being quantized. + // Depending on the bitmap & downscaling, it may have pixels that are less than opaque + // Ignore those pixels. + /// + // Note: they don't _have_ to be ignored, for example, we could instead turn them + // opaque. Traditionally, including outside Android, quantizers ignore transparent + // pixels, so that strategy was chosen. + int alpha = (pixel >> 24); + if (alpha < 255) { + continue; + } Integer currentCount = mCountByColor.get(pixel); if (currentCount == null) { currentCount = 0;