Chromium Code Reviews| Index: ui/gfx/color_analysis.cc |
| diff --git a/ui/gfx/color_analysis.cc b/ui/gfx/color_analysis.cc |
| index 6a2e87850f69ddbdfc9b2656616dcf5409b0310a..c294e9e7faf240d38b9e26d0fcdb57a6340928ae 100644 |
| --- a/ui/gfx/color_analysis.cc |
| +++ b/ui/gfx/color_analysis.cc |
| @@ -356,10 +356,11 @@ 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<HSL>& lower_bounds, |
| + const std::vector<HSL>& upper_bounds, |
| + const std::vector<HSL>& goals) { |
| DCHECK(!bitmap.empty()); |
| DCHECK(!bitmap.isNull()); |
| @@ -395,7 +396,7 @@ SkColor CalculateProminentColor(const SkBitmap& bitmap, |
| } |
| if (interesting_colors.empty()) |
| - return SK_ColorTRANSPARENT; |
| + return std::vector<SkColor>(goals.size(), SK_ColorTRANSPARENT); |
|
Evan Stade
2017/06/20 23:07:53
nit: maybe put the best_colors initialization abov
Qiang(Joe) Xu
2017/06/21 01:10:52
Done.
|
| // 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 +431,31 @@ 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; |
| - |
| - 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; |
| + std::vector<SkColor> best_colors(goals.size(), SK_ColorTRANSPARENT); |
| + for (size_t i = 0; i < goals.size(); ++i) { |
|
Evan Stade
2017/06/20 23:07:53
nit: I think this loop would be cleaner (and you'd
Qiang(Joe) Xu
2017/06/21 01:10:52
Done.
|
| + double best_suitability = 0; |
| + for (const auto& box_color : box_colors) { |
| + HSL hsl; |
| + SkColorToHSL(box_color.color, &hsl); |
| + if (!IsWithinHSLRange(hsl, lower_bounds[i], upper_bounds[i])) |
| + continue; |
| + |
| + double suitability = |
| + (1 - std::abs(hsl.s - goals[i].s)) * 3 + |
| + (1 - std::abs(hsl.l - goals[i].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 +726,51 @@ 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 ColorProfiles& color_profiles) { |
| + 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<HSL> lower_bounds(size, {-1}); |
|
danakj
2017/06/20 23:22:03
3 mallocs per call to this function is not awesome
Qiang(Joe) Xu
2017/06/21 01:10:52
Done.
|
| + std::vector<HSL> upper_bounds(size, {-1}); |
| + std::vector<HSL> goals(size, {-1}); |
| + for (size_t i = 0; i < size; ++i) { |
| + switch (color_profiles[i].luma) { |
| + case LumaRange::LIGHT: |
| + lower_bounds[i].l = 0.55f; |
| + upper_bounds[i].l = 1; |
| + goals[i].l = 0.74f; |
| + break; |
| + case LumaRange::NORMAL: |
| + lower_bounds[i].l = 0.3f; |
| + upper_bounds[i].l = 0.7f; |
| + goals[i].l = 0.5f; |
| + break; |
| + case LumaRange::DARK: |
| + lower_bounds[i].l = 0; |
| + upper_bounds[i].l = 0.45f; |
| + goals[i].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: |
| + lower_bounds[i].s = 0.35f; |
| + upper_bounds[i].s = 1; |
| + goals[i].s = 1; |
| + break; |
| + case SaturationRange::MUTED: |
| + lower_bounds[i].s = 0; |
| + upper_bounds[i].s = 0.4f; |
| + goals[i].s = 0.3f; |
| + break; |
| + } |
| } |
| - return CalculateProminentColor(bitmap, lower_bound, upper_bound, goal); |
| + return CalculateProminentColors(bitmap, lower_bounds, upper_bounds, goals); |
| } |
| gfx::Matrix3F ComputeColorCovariance(const SkBitmap& bitmap) { |