diff options
Diffstat (limited to 'chromium/ui/gfx/color_analysis.cc')
-rw-r--r-- | chromium/ui/gfx/color_analysis.cc | 74 |
1 files changed, 42 insertions, 32 deletions
diff --git a/chromium/ui/gfx/color_analysis.cc b/chromium/ui/gfx/color_analysis.cc index f8987cfb546..5cae9b6d4cc 100644 --- a/chromium/ui/gfx/color_analysis.cc +++ b/chromium/ui/gfx/color_analysis.cc @@ -13,14 +13,17 @@ #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkUnPreMultiply.h" #include "ui/gfx/codec/png_codec.h" +#include "ui/gfx/color_utils.h" +namespace color_utils { namespace { // RGBA KMean Constants const uint32_t kNumberOfClusters = 4; const int kNumberOfIterations = 50; -const uint32_t kMaxBrightness = 665; -const uint32_t kMinDarkness = 100; + +const HSL kDefaultLowerHSLBound = {-1, -1, 0.15}; +const HSL kDefaultUpperHSLBound = {-1, -1, 0.85}; // Background Color Modification Constants const SkColor kDefaultBgColor = SK_ColorWHITE; @@ -139,8 +142,6 @@ void UnPreMultiply(const SkBitmap& bitmap, uint32_t* buffer, int buffer_size) { } // namespace -namespace color_utils { - KMeanImageSampler::KMeanImageSampler() { } @@ -214,8 +215,8 @@ SkColor FindClosestColor(const uint8_t* image, SkColor CalculateKMeanColorOfBuffer(uint8_t* decoded_data, int img_width, int img_height, - uint32_t darkness_limit, - uint32_t brightness_limit, + const HSL& lower_bound, + const HSL& upper_bound, KMeanImageSampler* sampler) { SkColor color = kDefaultBgColor; if (img_width > 0 && img_height > 0) { @@ -331,21 +332,19 @@ SkColor CalculateKMeanColorOfBuffer(uint8_t* decoded_data, cluster != clusters.end(); ++cluster) { uint8_t r, g, b; cluster->GetCentroid(&r, &g, &b); - // Sum the RGB components to determine if the color is too bright or too - // dark. - // TODO (dtrainor): Look into using HSV here instead. This approximation - // might be fine though. - uint32_t summed_color = r + g + b; - if (summed_color < brightness_limit && summed_color > darkness_limit) { + SkColor current_color = SkColorSetARGB(SK_AlphaOPAQUE, r, g, b); + HSL hsl; + SkColorToHSL(current_color, &hsl); + if (IsWithinHSLRange(hsl, lower_bound, upper_bound)) { // If we found a valid color just set it and break. We don't want to // check the other ones. - color = SkColorSetARGB(0xFF, r, g, b); + color = current_color; break; } else if (cluster == clusters.begin()) { // We haven't found a valid color, but we are at the first color so // set the color anyway to make sure we at least have a value here. - color = SkColorSetARGB(0xFF, r, g, b); + color = current_color; } } } @@ -356,16 +355,15 @@ SkColor CalculateKMeanColorOfBuffer(uint8_t* decoded_data, } SkColor CalculateKMeanColorOfPNG(scoped_refptr<base::RefCountedMemory> png, - uint32_t darkness_limit, - uint32_t brightness_limit, + const HSL& lower_bound, + const HSL& upper_bound, KMeanImageSampler* sampler) { int img_width = 0; int img_height = 0; std::vector<uint8_t> decoded_data; SkColor color = kDefaultBgColor; - if (png.get() && - png->size() && + if (png.get() && png->size() && gfx::PNGCodec::Decode(png->front(), png->size(), gfx::PNGCodec::FORMAT_BGRA, @@ -375,14 +373,23 @@ SkColor CalculateKMeanColorOfPNG(scoped_refptr<base::RefCountedMemory> png, return CalculateKMeanColorOfBuffer(&decoded_data[0], img_width, img_height, - darkness_limit, - brightness_limit, + lower_bound, + upper_bound, sampler); } return color; } -SkColor CalculateKMeanColorOfBitmap(const SkBitmap& bitmap) { +SkColor CalculateKMeanColorOfPNG(scoped_refptr<base::RefCountedMemory> png) { + GridSampler sampler; + return CalculateKMeanColorOfPNG( + png, kDefaultLowerHSLBound, kDefaultUpperHSLBound, &sampler); +} + +SkColor CalculateKMeanColorOfBitmap(const SkBitmap& bitmap, + const HSL& lower_bound, + const HSL& upper_bound, + KMeanImageSampler* sampler) { // SkBitmap uses pre-multiplied alpha but the KMean clustering function // above uses non-pre-multiplied alpha. Transform the bitmap before we // analyze it because the function reads each pixel multiple times. @@ -390,15 +397,18 @@ SkColor CalculateKMeanColorOfBitmap(const SkBitmap& bitmap) { scoped_ptr<uint32_t[]> image(new uint32_t[pixel_count]); UnPreMultiply(bitmap, image.get(), pixel_count); + return CalculateKMeanColorOfBuffer(reinterpret_cast<uint8_t*>(image.get()), + bitmap.width(), + bitmap.height(), + lower_bound, + upper_bound, + sampler); +} + +SkColor CalculateKMeanColorOfBitmap(const SkBitmap& bitmap) { GridSampler sampler; - SkColor color = CalculateKMeanColorOfBuffer( - reinterpret_cast<uint8_t*>(image.get()), - bitmap.width(), - bitmap.height(), - kMinDarkness, - kMaxBrightness, - &sampler); - return color; + return CalculateKMeanColorOfBitmap( + bitmap, kDefaultLowerHSLBound, kDefaultUpperHSLBound, &sampler); } gfx::Matrix3F ComputeColorCovariance(const SkBitmap& bitmap) { @@ -409,7 +419,7 @@ gfx::Matrix3F ComputeColorCovariance(const SkBitmap& bitmap) { return covariance; // Assume ARGB_8888 format. - DCHECK(bitmap.config() == SkBitmap::kARGB_8888_Config); + DCHECK(bitmap.colorType() == kPMColor_SkColorType); int64_t r_sum = 0; int64_t g_sum = 0; @@ -478,8 +488,8 @@ bool ApplyColorReduction(const SkBitmap& source_bitmap, DCHECK(source_bitmap.getPixels()); DCHECK(target_bitmap->getPixels()); - DCHECK_EQ(SkBitmap::kARGB_8888_Config, source_bitmap.config()); - DCHECK_EQ(SkBitmap::kA8_Config, target_bitmap->config()); + DCHECK_EQ(kPMColor_SkColorType, source_bitmap.colorType()); + DCHECK_EQ(kAlpha_8_SkColorType, target_bitmap->colorType()); DCHECK_EQ(source_bitmap.height(), target_bitmap->height()); DCHECK_EQ(source_bitmap.width(), target_bitmap->width()); DCHECK(!source_bitmap.empty()); |