Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/gfx/color_analysis.h" | 5 #include "ui/gfx/color_analysis.h" |
| 6 | 6 |
| 7 #include <limits.h> | 7 #include <limits.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 448 (box_color.weight / static_cast<float>(max_weight)) * 0.5; | 448 (box_color.weight / static_cast<float>(max_weight)) * 0.5; |
| 449 if (suitability > best_suitability) { | 449 if (suitability > best_suitability) { |
| 450 best_suitability = suitability; | 450 best_suitability = suitability; |
| 451 best_color = box_color.color; | 451 best_color = box_color.color; |
| 452 } | 452 } |
| 453 } | 453 } |
| 454 | 454 |
| 455 return best_color; | 455 return best_color; |
| 456 } | 456 } |
| 457 | 457 |
| 458 SkColor CalculateProminentColorOfBitmap(const SkBitmap& bitmap, | |
| 459 LumaRange luma, | |
| 460 SaturationRange saturation) { | |
| 461 if (bitmap.empty() || bitmap.isNull()) | |
| 462 return SK_ColorTRANSPARENT; | |
| 463 | |
| 464 // The hue is not relevant to our bounds or goal colors. | |
| 465 HSL lower_bound = { | |
| 466 -1, | |
| 467 }; | |
| 468 HSL upper_bound = { | |
| 469 -1, | |
| 470 }; | |
| 471 HSL goal = { | |
| 472 -1, | |
| 473 }; | |
| 474 | |
| 475 switch (luma) { | |
| 476 case LumaRange::LIGHT: | |
| 477 lower_bound.l = 0.55f; | |
| 478 upper_bound.l = 1; | |
| 479 goal.l = 0.74f; | |
| 480 break; | |
| 481 case LumaRange::NORMAL: | |
| 482 lower_bound.l = 0.3f; | |
| 483 upper_bound.l = 0.7f; | |
| 484 goal.l = 0.5f; | |
| 485 break; | |
| 486 case LumaRange::DARK: | |
| 487 lower_bound.l = 0; | |
| 488 upper_bound.l = 0.45f; | |
| 489 goal.l = 0.26f; | |
| 490 break; | |
| 491 } | |
| 492 | |
| 493 switch (saturation) { | |
| 494 case SaturationRange::VIBRANT: | |
| 495 lower_bound.s = 0.35f; | |
| 496 upper_bound.s = 1; | |
| 497 goal.s = 1; | |
| 498 break; | |
| 499 case SaturationRange::MUTED: | |
| 500 lower_bound.s = 0; | |
| 501 upper_bound.s = 0.4f; | |
| 502 goal.s = 0.3f; | |
| 503 break; | |
| 504 } | |
| 505 | |
| 506 return CalculateProminentColor(bitmap, lower_bound, upper_bound, goal); | |
|
bruthig
2017/06/20 15:32:14
estade@ will be able to better advise but IIUC Cal
Evan Stade
2017/06/20 17:11:08
yes, as explained in the email, we only want to re
Qiang(Joe) Xu
2017/06/20 22:48:55
done, thanks for explaining!
| |
| 507 } | |
| 508 | |
| 458 } // namespace | 509 } // namespace |
| 459 | 510 |
| 460 KMeanImageSampler::KMeanImageSampler() { | 511 KMeanImageSampler::KMeanImageSampler() { |
| 461 } | 512 } |
| 462 | 513 |
| 463 KMeanImageSampler::~KMeanImageSampler() { | 514 KMeanImageSampler::~KMeanImageSampler() { |
| 464 } | 515 } |
| 465 | 516 |
| 466 GridSampler::GridSampler() : calls_(0) { | 517 GridSampler::GridSampler() : calls_(0) { |
| 467 } | 518 } |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 716 bitmap.width(), bitmap.height(), | 767 bitmap.width(), bitmap.height(), |
| 717 lower_bound, upper_bound, sampler); | 768 lower_bound, upper_bound, sampler); |
| 718 } | 769 } |
| 719 | 770 |
| 720 SkColor CalculateKMeanColorOfBitmap(const SkBitmap& bitmap) { | 771 SkColor CalculateKMeanColorOfBitmap(const SkBitmap& bitmap) { |
| 721 GridSampler sampler; | 772 GridSampler sampler; |
| 722 return CalculateKMeanColorOfBitmap( | 773 return CalculateKMeanColorOfBitmap( |
| 723 bitmap, kDefaultLowerHSLBound, kDefaultUpperHSLBound, &sampler); | 774 bitmap, kDefaultLowerHSLBound, kDefaultUpperHSLBound, &sampler); |
| 724 } | 775 } |
| 725 | 776 |
| 726 SkColor CalculateProminentColorOfBitmap(const SkBitmap& bitmap, | 777 std::vector<SkColor> CalculateProminentColorsOfBitmap( |
| 727 LumaRange luma, | 778 const SkBitmap& bitmap, |
| 728 SaturationRange saturation) { | 779 const ColorProfiles& color_profiles) { |
| 729 if (bitmap.empty() || bitmap.isNull()) | 780 std::vector<SkColor> colors; |
| 730 return SK_ColorTRANSPARENT; | 781 for (auto profile : color_profiles) { |
| 731 | 782 colors.push_back(CalculateProminentColorOfBitmap(bitmap, profile.luma, |
| 732 // The hue is not relevant to our bounds or goal colors. | 783 profile.saturation)); |
| 733 HSL lower_bound = { | |
| 734 -1, | |
| 735 }; | |
| 736 HSL upper_bound = { | |
| 737 -1, | |
| 738 }; | |
| 739 HSL goal = { | |
| 740 -1, | |
| 741 }; | |
| 742 | |
| 743 switch (luma) { | |
| 744 case LumaRange::LIGHT: | |
| 745 lower_bound.l = 0.55f; | |
| 746 upper_bound.l = 1; | |
| 747 goal.l = 0.74f; | |
| 748 break; | |
| 749 case LumaRange::NORMAL: | |
| 750 lower_bound.l = 0.3f; | |
| 751 upper_bound.l = 0.7f; | |
| 752 goal.l = 0.5f; | |
| 753 break; | |
| 754 case LumaRange::DARK: | |
| 755 lower_bound.l = 0; | |
| 756 upper_bound.l = 0.45f; | |
| 757 goal.l = 0.26f; | |
| 758 break; | |
| 759 } | 784 } |
| 760 | 785 return colors; |
| 761 switch (saturation) { | |
| 762 case SaturationRange::VIBRANT: | |
| 763 lower_bound.s = 0.35f; | |
| 764 upper_bound.s = 1; | |
| 765 goal.s = 1; | |
| 766 break; | |
| 767 case SaturationRange::MUTED: | |
| 768 lower_bound.s = 0; | |
| 769 upper_bound.s = 0.4f; | |
| 770 goal.s = 0.3f; | |
| 771 break; | |
| 772 } | |
| 773 | |
| 774 return CalculateProminentColor(bitmap, lower_bound, upper_bound, goal); | |
| 775 } | 786 } |
| 776 | 787 |
| 777 gfx::Matrix3F ComputeColorCovariance(const SkBitmap& bitmap) { | 788 gfx::Matrix3F ComputeColorCovariance(const SkBitmap& bitmap) { |
| 778 // First need basic stats to normalize each channel separately. | 789 // First need basic stats to normalize each channel separately. |
| 779 gfx::Matrix3F covariance = gfx::Matrix3F::Zeros(); | 790 gfx::Matrix3F covariance = gfx::Matrix3F::Zeros(); |
| 780 if (!bitmap.getPixels()) | 791 if (!bitmap.getPixels()) |
| 781 return covariance; | 792 return covariance; |
| 782 | 793 |
| 783 // Assume ARGB_8888 format. | 794 // Assume ARGB_8888 format. |
| 784 DCHECK(bitmap.colorType() == kN32_SkColorType); | 795 DCHECK(bitmap.colorType() == kN32_SkColorType); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 932 gfx::Matrix3F covariance = ComputeColorCovariance(source_bitmap); | 943 gfx::Matrix3F covariance = ComputeColorCovariance(source_bitmap); |
| 933 gfx::Matrix3F eigenvectors = gfx::Matrix3F::Zeros(); | 944 gfx::Matrix3F eigenvectors = gfx::Matrix3F::Zeros(); |
| 934 gfx::Vector3dF eigenvals = covariance.SolveEigenproblem(&eigenvectors); | 945 gfx::Vector3dF eigenvals = covariance.SolveEigenproblem(&eigenvectors); |
| 935 gfx::Vector3dF principal = eigenvectors.get_column(0); | 946 gfx::Vector3dF principal = eigenvectors.get_column(0); |
| 936 if (eigenvals == gfx::Vector3dF() || principal == gfx::Vector3dF()) | 947 if (eigenvals == gfx::Vector3dF() || principal == gfx::Vector3dF()) |
| 937 return false; // This may happen for some edge cases. | 948 return false; // This may happen for some edge cases. |
| 938 return ApplyColorReduction(source_bitmap, principal, true, target_bitmap); | 949 return ApplyColorReduction(source_bitmap, principal, true, target_bitmap); |
| 939 } | 950 } |
| 940 | 951 |
| 941 } // color_utils | 952 } // color_utils |
| OLD | NEW |