summaryrefslogtreecommitdiffstats
path: root/chromium/ui/gfx/color_analysis.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ui/gfx/color_analysis.cc')
-rw-r--r--chromium/ui/gfx/color_analysis.cc74
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());