Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(308)

Unified Diff: ui/gfx/color_analysis.h

Issue 7031078: Retry r88137: (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix for test failures Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ui/gfx/color_analysis.h
diff --git a/ui/gfx/color_analysis.h b/ui/gfx/color_analysis.h
new file mode 100644
index 0000000000000000000000000000000000000000..c71a38603b7119ee684a35ffdd27adba7b7dcf1a
--- /dev/null
+++ b/ui/gfx/color_analysis.h
@@ -0,0 +1,112 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_GFX_COLOR_ANALYSIS_H_
+#define UI_GFX_COLOR_ANALYSIS_H_
+#pragma once
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/ref_counted_memory.h"
+#include "third_party/skia/include/core/SkColor.h"
+
+namespace color_utils {
+
+// This class exposes the sampling method to the caller, which allows
+// stubbing out for things like unit tests. Might be useful to pass more
+// arguments into the GetSample method in the future (such as which
+// cluster is being worked on, etc.).
+class KMeanImageSampler {
+ public:
+ virtual int GetSample(int width, int height) = 0;
+
+ protected:
+ KMeanImageSampler();
+ virtual ~KMeanImageSampler();
+};
+
+// This sampler will pick a random pixel as a sample centroid.
+class RandomSampler : public KMeanImageSampler {
+ public:
+ RandomSampler();
+ virtual ~RandomSampler();
+
+ virtual int GetSample(int width, int height) OVERRIDE;
+};
+
+// This sampler will pick pixels from an evenly spaced grid.
+class GridSampler : public KMeanImageSampler {
+ public:
+ GridSampler();
+ virtual ~GridSampler();
+
+ virtual int GetSample(int width, int height) OVERRIDE;
+
+ private:
+ // The number of times GetSample has been called.
+ int calls_;
+};
+
+// Returns a recommended background color for a PNG image. This color might
+// not even exist in the image, but it is typically representative of the
+// image and tinted towards the white end of the spectrum.
+// The function CalculateKMeanColorOfPNG is used to grab the KMean calculated
+// color of the image, then the color is moved to HSV space so the saturation
+// and luminance can be modified to move the color towards the white end of
+// the spectrum. The color is then moved back to RGB space and returned.
+SkColor CalculateRecommendedBgColorForPNG(scoped_refptr<RefCountedMemory> png);
+
+SkColor CalculateRecommendedBgColorForPNG(scoped_refptr<RefCountedMemory> png,
+ KMeanImageSampler& sampler);
+
+// Returns an SkColor that represents the calculated dominant color in the png.
+// This uses a KMean clustering algorithm to find clusters of pixel colors in
+// RGB space.
+// |png| represents the data of a png encoded image.
+// |darkness_limit| represents the minimum sum of the RGB components that is
+// acceptable as a color choice. This can be from 0 to 765.
+// |brightness_limit| represents the maximum sum of the RGB components that is
+// acceptable as a color choice. This can be from 0 to 765.
+//
+// RGB KMean Algorithm (N clusters, M iterations):
+// TODO (dtrainor): Try moving most/some of this to HSV space? Better for
+// color comparisons/averages?
+// 1.Pick N starting colors by randomly sampling the pixels. If you see a
+// color you already saw keep sampling. After a certain number of tries
+// just remove the cluster and continue with N = N-1 clusters (for an image
+// with just one color this should devolve to N=1). These colors are the
+// centers of your N clusters.
+// TODO (dtrainor): Check to ignore colors with an alpha of 0?
+// 2.For each pixel in the image find the cluster that it is closest to in RGB
+// space. Add that pixel's color to that cluster (we keep a sum and a count
+// of all of the pixels added to the space, so just add it to the sum and
+// increment count).
+// 3.Calculate the new cluster centroids by getting the average color of all of
+// the pixels in each cluster (dividing the sum by the count).
+// 4.See if the new centroids are the same as the old centroids.
+// a) If this is the case for all N clusters than we have converged and
+// can move on.
+// b) If any centroid moved, repeat step 2 with the new centroids for up
+// to M iterations.
+// 5.Once the clusters have converged or M iterations have been tried, sort
+// the clusters by weight (where weight is the number of pixels that make up
+// this cluster).
+// 6.Going through the sorted list of clusters, pick the first cluster with the
+// largest weight that's centroid fulfills the equation
+// |darkness_limit| < SUM(R, G, B) < |brightness_limit|. Return that color.
+// If no color fulfills that requirement return the color with the largest
+// weight regardless of whether or not it fulfills the equation above.
+SkColor CalculateKMeanColorOfPNG(scoped_refptr<RefCountedMemory> png,
+ uint32_t darkness_limit,
+ uint32_t brightness_limit);
+
+SkColor CalculateKMeanColorOfPNG(scoped_refptr<RefCountedMemory> png,
+ uint32_t darkness_limit,
+ uint32_t brightness_limit,
+ KMeanImageSampler& sampler);
+
+} // namespace color_utils
+
+#endif // UI_GFX_COLOR_ANALYSIS_H_

Powered by Google App Engine
This is Rietveld 408576698