Skip to content

Commit

Permalink
app: ui: Use gradients on android versions without blur support
Browse files Browse the repository at this point in the history
* Cherry-pick of 7ee7dd7
  • Loading branch information
DD3Boh authored and mikooomich committed Jan 5, 2025
1 parent 6889b03 commit c030129
Showing 1 changed file with 89 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@

package com.google.material.color.score;

import com.google.material.color.hct.Cam16;
import com.google.material.color.hct.Hct;
import com.google.material.color.utils.MathUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

Expand Down Expand Up @@ -157,6 +159,83 @@ public static List<Integer> score(
return colors;
}

/**
* Given a map with keys of colors and values of how often the color appears, rank the colors
* based on it and discard colors too close to each other.
*
* @param colorsToPopulation map with keys of colors and values of how often the color appears,
* usually from a source image.
* @return Colors sorted by population. The most suitable color is the first item,
* the least suitable is the last.
* The list might be empty.
*/
public static List<Integer> order(Map<Integer, Integer> colorsToPopulation) {
// Determine the total count of all colors.
double populationSum = 0.;
for (Map.Entry<Integer, Integer> entry : colorsToPopulation.entrySet()) {
populationSum += entry.getValue();
}
// Turn the count of each color into a proportion by dividing by the total
// count. Also, fill a cache of CAM16 colors representing each color, and
// record the proportion of colors for each CAM16 hue.
Map<Integer, Cam16> colorsToCam = new HashMap<>();
double[] hueProportions = new double[361];
for (Map.Entry<Integer, Integer> entry : colorsToPopulation.entrySet()) {
int color = entry.getKey();
double population = entry.getValue();
double proportion = population / populationSum;
Cam16 cam = Cam16.fromInt(color);
colorsToCam.put(color, cam);
int hue = (int) Math.round(cam.getHue());
hueProportions[hue] += proportion;
}
// Determine the proportion of the colors around each color, by summing the
// proportions around each color's hue.
Map<Integer, Double> colorsToExcitedProportion = new HashMap<>();
for (Map.Entry<Integer, Cam16> entry : colorsToCam.entrySet()) {
int color = entry.getKey();
Cam16 cam = entry.getValue();
int hue = (int) Math.round(cam.getHue());
double excitedProportion = 0.;
for (int j = (hue - 15); j < (hue + 15); j++) {
int neighborHue = MathUtils.sanitizeDegreesInt(j);
excitedProportion += hueProportions[neighborHue];
}
colorsToExcitedProportion.put(color, excitedProportion);
}
// Score the colors by their proportion.
Map<Integer, Double> colorsToScore = new HashMap<>();
for (Map.Entry<Integer, Cam16> entry : colorsToCam.entrySet()) {
int color = entry.getKey();
double proportion = colorsToExcitedProportion.get(color);
double proportionScore = proportion * 100.0 * WEIGHT_PROPORTION;
colorsToScore.put(color, proportionScore);
}
// Ensure the list of colors returned is sorted such that the first in the
// list is the most suitable, and the last is the least suitable.
List<Map.Entry<Integer, Double>> entryList = new ArrayList<>(colorsToScore.entrySet());
entryList.sort(new OldScoredComparator());
List<Integer> colorsByScoreDescending = new ArrayList<>();
for (Map.Entry<Integer, Double> entry : entryList) {
int color = entry.getKey();
Cam16 cam = colorsToCam.get(color);
boolean duplicateHue = false;
for (Integer alreadyChosenColor : colorsByScoreDescending) {
Cam16 alreadyChosenCam = colorsToCam.get(alreadyChosenColor);
if (MathUtils.differenceDegrees(cam.getHue(), alreadyChosenCam.getHue()) < 15) {
duplicateHue = true;
break;
}
}
if (duplicateHue) {
continue;
}
colorsByScoreDescending.add(entry.getKey());
}
return colorsByScoreDescending;
}


private static class ScoredHCT {
public final Hct hct;
public final double score;
Expand All @@ -176,4 +255,14 @@ public int compare(ScoredHCT entry1, ScoredHCT entry2) {
return Double.compare(entry2.score, entry1.score);
}
}

static class OldScoredComparator implements Comparator<Map.Entry<Integer, Double>> {
public OldScoredComparator() {
}

@Override
public int compare(Map.Entry<Integer, Double> entry1, Map.Entry<Integer, Double> entry2) {
return -entry1.getValue().compareTo(entry2.getValue());
}
}
}

0 comments on commit c030129

Please sign in to comment.