Index: ui/gfx/color_analysis.cc |
diff --git a/ui/gfx/color_analysis.cc b/ui/gfx/color_analysis.cc |
index 6a2e87850f69ddbdfc9b2656616dcf5409b0310a..bbe2d0c6b21cd89dafd48a41c2555a1951bd4a6c 100644 |
--- a/ui/gfx/color_analysis.cc |
+++ b/ui/gfx/color_analysis.cc |
@@ -349,6 +349,14 @@ bool IsInterestingColor(SkColor color) { |
return !(hsl.h >= 0.028f && hsl.h <= 0.10f && hsl.s <= 0.82f); |
} |
+// Used to group lower_bound, upper_bound, goal HSL color together for prominent |
+// color calculation. |
+struct ColorBracket { |
+ HSL lower_bound = {-1}; |
+ HSL upper_bound = {-1}; |
+ HSL goal = {-1}; |
+}; |
+ |
// This algorithm is a port of Android's Palette API. Compare to package |
// android.support.v7.graphics and see that code for additional high-level |
// explanation of this algorithm. There are some minor differences: |
@@ -356,10 +364,9 @@ bool IsInterestingColor(SkColor color) { |
// different color profiles. |
// * This code doesn't try to heuristically derive missing colors from |
// existing colors. |
-SkColor CalculateProminentColor(const SkBitmap& bitmap, |
- const HSL& lower_bound, |
- const HSL& upper_bound, |
- const HSL& goal) { |
+std::vector<SkColor> CalculateProminentColors( |
+ const SkBitmap& bitmap, |
+ const std::vector<ColorBracket>& color_brackets) { |
DCHECK(!bitmap.empty()); |
DCHECK(!bitmap.isNull()); |
@@ -394,8 +401,9 @@ SkColor CalculateProminentColor(const SkBitmap& bitmap, |
interesting_colors.push_back(color); |
} |
+ std::vector<SkColor> best_colors(color_brackets.size(), SK_ColorTRANSPARENT); |
if (interesting_colors.empty()) |
- return SK_ColorTRANSPARENT; |
+ return best_colors; |
// Group the colors into "boxes" and repeatedly split the most voluminous box. |
// We stop the process when a box can no longer be split (there's only one |
@@ -430,29 +438,32 @@ SkColor CalculateProminentColor(const SkBitmap& bitmap, |
max_weight = std::max(max_weight, box_colors.back().weight); |
} |
- // Given these box average colors, find the best one for the desired color |
+ // Given these box average colors, find the best one for each desired color |
// profile. "Best" in this case means the color which fits in the provided |
// bounds and comes closest to |goal|. It's possible that no color will fit in |
// the provided bounds, in which case we'll return an empty color. |
- double best_suitability = 0; |
- SkColor best_color = SK_ColorTRANSPARENT; |
- for (const auto& box_color : box_colors) { |
- HSL hsl; |
- SkColorToHSL(box_color.color, &hsl); |
- if (!IsWithinHSLRange(hsl, lower_bound, upper_bound)) |
- continue; |
+ for (size_t i = 0; i < color_brackets.size(); ++i) { |
+ double best_suitability = 0; |
+ for (const auto& box_color : box_colors) { |
+ HSL hsl; |
+ SkColorToHSL(box_color.color, &hsl); |
+ if (!IsWithinHSLRange(hsl, color_brackets[i].lower_bound, |
+ color_brackets[i].upper_bound)) { |
+ continue; |
+ } |
- double suitability = |
- (1 - std::abs(hsl.s - goal.s)) * 3 + |
- (1 - std::abs(hsl.l - goal.l)) * 6.5 + |
- (box_color.weight / static_cast<float>(max_weight)) * 0.5; |
- if (suitability > best_suitability) { |
- best_suitability = suitability; |
- best_color = box_color.color; |
+ double suitability = |
+ (1 - std::abs(hsl.s - color_brackets[i].goal.s)) * 3 + |
+ (1 - std::abs(hsl.l - color_brackets[i].goal.l)) * 6.5 + |
+ (box_color.weight / static_cast<float>(max_weight)) * 0.5; |
+ if (suitability > best_suitability) { |
+ best_suitability = suitability; |
+ best_colors[i] = box_color.color; |
+ } |
} |
} |
- return best_color; |
+ return best_colors; |
} |
} // namespace |
@@ -723,55 +734,52 @@ SkColor CalculateKMeanColorOfBitmap(const SkBitmap& bitmap) { |
bitmap, kDefaultLowerHSLBound, kDefaultUpperHSLBound, &sampler); |
} |
-SkColor CalculateProminentColorOfBitmap(const SkBitmap& bitmap, |
- LumaRange luma, |
- SaturationRange saturation) { |
+std::vector<SkColor> CalculateProminentColorsOfBitmap( |
+ const SkBitmap& bitmap, |
+ const std::vector<ColorProfile>& color_profiles) { |
+ if (color_profiles.empty()) |
+ return std::vector<SkColor>(); |
+ |
+ size_t size = color_profiles.size(); |
if (bitmap.empty() || bitmap.isNull()) |
- return SK_ColorTRANSPARENT; |
+ return std::vector<SkColor>(size, SK_ColorTRANSPARENT); |
// The hue is not relevant to our bounds or goal colors. |
- HSL lower_bound = { |
- -1, |
- }; |
- HSL upper_bound = { |
- -1, |
- }; |
- HSL goal = { |
- -1, |
- }; |
- |
- switch (luma) { |
- case LumaRange::LIGHT: |
- lower_bound.l = 0.55f; |
- upper_bound.l = 1; |
- goal.l = 0.74f; |
- break; |
- case LumaRange::NORMAL: |
- lower_bound.l = 0.3f; |
- upper_bound.l = 0.7f; |
- goal.l = 0.5f; |
- break; |
- case LumaRange::DARK: |
- lower_bound.l = 0; |
- upper_bound.l = 0.45f; |
- goal.l = 0.26f; |
- break; |
- } |
+ std::vector<ColorBracket> color_brackets(size); |
+ for (size_t i = 0; i < size; ++i) { |
+ switch (color_profiles[i].luma) { |
+ case LumaRange::LIGHT: |
+ color_brackets[i].lower_bound.l = 0.55f; |
+ color_brackets[i].upper_bound.l = 1; |
+ color_brackets[i].goal.l = 0.74f; |
+ break; |
+ case LumaRange::NORMAL: |
+ color_brackets[i].lower_bound.l = 0.3f; |
+ color_brackets[i].upper_bound.l = 0.7f; |
+ color_brackets[i].goal.l = 0.5f; |
+ break; |
+ case LumaRange::DARK: |
+ color_brackets[i].lower_bound.l = 0; |
+ color_brackets[i].upper_bound.l = 0.45f; |
+ color_brackets[i].goal.l = 0.26f; |
+ break; |
+ } |
- switch (saturation) { |
- case SaturationRange::VIBRANT: |
- lower_bound.s = 0.35f; |
- upper_bound.s = 1; |
- goal.s = 1; |
- break; |
- case SaturationRange::MUTED: |
- lower_bound.s = 0; |
- upper_bound.s = 0.4f; |
- goal.s = 0.3f; |
- break; |
+ switch (color_profiles[i].saturation) { |
+ case SaturationRange::VIBRANT: |
+ color_brackets[i].lower_bound.s = 0.35f; |
+ color_brackets[i].upper_bound.s = 1; |
+ color_brackets[i].goal.s = 1; |
+ break; |
+ case SaturationRange::MUTED: |
+ color_brackets[i].lower_bound.s = 0; |
+ color_brackets[i].upper_bound.s = 0.4f; |
+ color_brackets[i].goal.s = 0.3f; |
+ break; |
+ } |
} |
- return CalculateProminentColor(bitmap, lower_bound, upper_bound, goal); |
+ return CalculateProminentColors(bitmap, color_brackets); |
} |
gfx::Matrix3F ComputeColorCovariance(const SkBitmap& bitmap) { |