取色

203 阅读1分钟
implementation 'androidx.palette:palette:1.0.0'

palette-1.0.0-sources.jar!\androidx\palette\graphics\Palette.java

public final class PaletteUtils {
    public static final String TAG = "PaletteUtils";
    private static final float BLACK_MAX_LIGHTNESS = 0.05f;
    private static final float WHITE_MIN_LIGHTNESS = 0.95f;

    private PaletteUtils() {
        throw new RuntimeException("Please don't create PaletteUtils instance via the private constructor.");
    }

    /**
     * 判断Bitmap是否是白色/几乎是白色
     *
     * @param bitmap
     * @return
     */
    public static boolean isBitmapWhite(Bitmap bitmap) {
        Palette p = getPalette(bitmap);
        if (null == p) {
            return false;
        }
        boolean result = whetherIsLight(p);
        Log.d(TAG, "isBitmapColorLight. result:" + result);
        return result;
    }

    /**
     * gain Palette instance via Bitmap
     *
     * @param bitmap
     * @return
     */
    private static Palette getPalette(Bitmap bitmap) {
        return Palette.from(bitmap)
                .setRegion(0, 0, bitmap.getWidth(), bitmap.getHeight())
                .clearFilters()
                .generate();
    }

    /**
     * 判断是否整体颜色属于 暗色
     *
     * @param wallpaperSwatches
     * @return
     */
    private static boolean whetherIsDark(List<Palette.Swatch> wallpaperSwatches) {
        int darkPopulation = 0;
        int lightPopulation = 0;
        double luminance = 0;
        for (Palette.Swatch swatch : wallpaperSwatches) {
            //正常使用0.5000d即可. 修改该值以调试.
            luminance = ColorUtils.calculateLuminance(swatch.getRgb());
            Log.d(TAG, "whetherIsDark. luminance:" + luminance);
            if (luminance < 0.900d) {
                darkPopulation += swatch.getPopulation();
            } else {
                lightPopulation += swatch.getPopulation();
            }
        }
        return darkPopulation > lightPopulation;
    }

    /**
     * 判断是否整体颜色属于 亮色
     *
     * @param wallpaperSwatches
     * @return
     */
    private static boolean whetherIsLight(List<Palette.Swatch> wallpaperSwatches) {
        int darkPopulation = 0;
        int lightPopulation = 0;
        double luminance = 0;
        for (Palette.Swatch swatch : wallpaperSwatches) {
            luminance = ColorUtils.calculateLuminance(swatch.getRgb());
            Log.d(TAG, "whetherLightDark. luminance:" + luminance);
            if (luminance < 0.05d) {
                lightPopulation += swatch.getPopulation();
            } else {
                darkPopulation += swatch.getPopulation();
            }
        }
        return lightPopulation > darkPopulation;
    }

    private static Palette.Swatch findDominantSwatch(List<Palette.Swatch> mSwatches) {
        int maxPop = Integer.MIN_VALUE;
        Palette.Swatch maxSwatch = null;
        for (int i = 0, count = mSwatches.size(); i < count; i++) {
            Palette.Swatch swatch = mSwatches.get(i);
            if (swatch.getPopulation() > maxPop) {
                maxSwatch = swatch;
                maxPop = swatch.getPopulation();
            }
        }
        return maxSwatch;
    }

    /**
     * 用于判断主色是否接近白色
     *
     * @param palette
     * @return
     */
    private static boolean whetherDominantIsLight(Palette palette) {
        Palette.Swatch dominantSwatch = findDominantSwatch(palette.getSwatches());
        float[] hsl = dominantSwatch.getHsl();
        Log.d(TAG, "whetherIsLight. hsl:" + hsl);
        boolean isWhite = isWhite(hsl);
        return isWhite;
    }

    /**
     * 判断整体颜色是否 是白色/几乎是白色
     *
     * @param palette
     * @return
     */
    private static boolean whetherIsLight(Palette palette) {
        List<Palette.Swatch> swatches = palette.getSwatches();
        float totalHsl2 = 0.0F;
        int population = 0;
        float hsl2 = 0.0F;
        int totalPopulation = 0;
        float[] hsl = null;
        float itemHsl = 0.0F;
        for (Palette.Swatch swatch : swatches) {
            hsl = swatch.getHsl();
            hsl2 = hsl[2];
            population = swatch.getPopulation();
            itemHsl = hsl2 * population;
            totalPopulation += population;
            totalHsl2 += itemHsl;
            Log.d(TAG, "whetherIsLight. hsl2:" + hsl2 + " ; population:" + population + " ; itemHsl:" + itemHsl);
        }
        float averageHsl2 = totalHsl2 / totalPopulation;
        boolean result = averageHsl2 >= WHITE_MIN_LIGHTNESS;
        Log.d(TAG, "whetherIsLight. totalHsl2:" + totalHsl2 + " ; totalPopulation:" + totalPopulation + " ; averageHsl2:" + averageHsl2 + " ; result:" + result);
        return result;
    }

    /**
     * check whether curr color is close to black.
     *
     * @param hslColor
     * @return true if the color represents a color which is close to black.
     */
    private static boolean isBlack(float[] hslColor) {
        return hslColor[2] <= BLACK_MAX_LIGHTNESS;
    }

    /**
     * check whether curr color is close to white.
     *
     * @param hslColor
     * @return true if the color represents a color which is close to white.
     */
    private static boolean isWhite(float[] hslColor) {
        boolean result = hslColor[2] >= WHITE_MIN_LIGHTNESS;
        Log.d(TAG, "isWhite. hslColor[2]:" + hslColor[2] + " ; result:" + result);
        return result;
    }
}