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 <vector> | 7 #include <vector> |
8 | 8 |
9 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
10 #include "third_party/skia/include/core/SkBitmap.h" | 10 #include "third_party/skia/include/core/SkBitmap.h" |
11 #include "third_party/skia/include/core/SkColor.h" | 11 #include "third_party/skia/include/core/SkColor.h" |
12 #include "ui/gfx/canvas.h" | 12 #include "ui/gfx/canvas.h" |
| 13 #include "ui/gfx/color_utils.h" |
| 14 #include "ui/gfx/image/image.h" |
13 #include "ui/gfx/rect.h" | 15 #include "ui/gfx/rect.h" |
14 | 16 |
15 namespace color_utils { | 17 namespace color_utils { |
16 | 18 |
17 const unsigned char k1x1White[] = { | 19 const unsigned char k1x1White[] = { |
18 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, | 20 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, |
19 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, | 21 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, |
20 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, | 22 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, |
21 0x08, 0x02, 0x00, 0x00, 0x00, 0x90, 0x77, 0x53, | 23 0x08, 0x02, 0x00, 0x00, 0x00, 0x90, 0x77, 0x53, |
22 0xde, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, | 24 0xde, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, | 80 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, |
79 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, | 81 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, |
80 0x81, 0x0e, 0x17, 0x00, 0x00, 0x00, 0x14, 0x49, | 82 0x81, 0x0e, 0x17, 0x00, 0x00, 0x00, 0x14, 0x49, |
81 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0xf8, 0xcf, | 83 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0xf8, 0xcf, |
82 0xc0, 0xc0, 0xc4, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, | 84 0xc0, 0xc0, 0xc4, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, |
83 0xf0, 0x1f, 0x00, 0x0c, 0x10, 0x02, 0x01, 0x2c, | 85 0xf0, 0x1f, 0x00, 0x0c, 0x10, 0x02, 0x01, 0x2c, |
84 0x8f, 0x8b, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x49, | 86 0x8f, 0x8b, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x49, |
85 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 | 87 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 |
86 }; | 88 }; |
87 | 89 |
| 90 const HSL kDefaultLowerBound = {-1, -1, 0.15}; |
| 91 const HSL kDefaultUpperBound = {-1, -1, 0.85}; |
| 92 |
| 93 // Creates a 1-dimensional png of the pixel colors found in |colors|. |
| 94 scoped_refptr<base::RefCountedMemory> CreateTestPNG( |
| 95 const std::vector<SkColor>& colors) { |
| 96 SkBitmap bitmap; |
| 97 bitmap.setConfig(SkBitmap::kARGB_8888_Config, colors.size(), 1); |
| 98 bitmap.allocPixels(); |
| 99 |
| 100 SkAutoLockPixels lock(bitmap); |
| 101 for (size_t i = 0; i < colors.size(); ++i) { |
| 102 bitmap.eraseArea(SkIRect::MakeXYWH(i, 0, 1, 1), colors[i]); |
| 103 } |
| 104 return gfx::Image::CreateFrom1xBitmap(bitmap).As1xPNGBytes(); |
| 105 } |
| 106 |
88 class MockKMeanImageSampler : public KMeanImageSampler { | 107 class MockKMeanImageSampler : public KMeanImageSampler { |
89 public: | 108 public: |
90 MockKMeanImageSampler() : current_result_index_(0) { | 109 MockKMeanImageSampler() : current_result_index_(0) { |
91 } | 110 } |
92 | 111 |
93 explicit MockKMeanImageSampler(const std::vector<int>& samples) | 112 explicit MockKMeanImageSampler(const std::vector<int>& samples) |
94 : prebaked_sample_results_(samples), | 113 : prebaked_sample_results_(samples), |
95 current_result_index_(0) { | 114 current_result_index_(0) { |
96 } | 115 } |
97 | 116 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 TEST_F(ColorAnalysisTest, CalculatePNGKMeanAllWhite) { | 170 TEST_F(ColorAnalysisTest, CalculatePNGKMeanAllWhite) { |
152 MockKMeanImageSampler test_sampler; | 171 MockKMeanImageSampler test_sampler; |
153 test_sampler.AddSample(0); | 172 test_sampler.AddSample(0); |
154 | 173 |
155 scoped_refptr<base::RefCountedBytes> png( | 174 scoped_refptr<base::RefCountedBytes> png( |
156 new base::RefCountedBytes( | 175 new base::RefCountedBytes( |
157 std::vector<unsigned char>( | 176 std::vector<unsigned char>( |
158 k1x1White, | 177 k1x1White, |
159 k1x1White + sizeof(k1x1White) / sizeof(unsigned char)))); | 178 k1x1White + sizeof(k1x1White) / sizeof(unsigned char)))); |
160 | 179 |
161 SkColor color = CalculateKMeanColorOfPNG(png, 100, 600, &test_sampler); | 180 SkColor color = CalculateKMeanColorOfPNG( |
| 181 png, kDefaultLowerBound, kDefaultUpperBound, &test_sampler); |
162 | 182 |
163 EXPECT_EQ(color, SK_ColorWHITE); | 183 EXPECT_EQ(color, SK_ColorWHITE); |
164 } | 184 } |
165 | 185 |
166 TEST_F(ColorAnalysisTest, CalculatePNGKMeanIgnoreWhite) { | 186 TEST_F(ColorAnalysisTest, CalculatePNGKMeanIgnoreWhiteLightness) { |
167 MockKMeanImageSampler test_sampler; | 187 MockKMeanImageSampler test_sampler; |
168 test_sampler.AddSample(0); | 188 test_sampler.AddSample(0); |
169 test_sampler.AddSample(1); | 189 test_sampler.AddSample(1); |
170 test_sampler.AddSample(2); | 190 test_sampler.AddSample(2); |
171 | 191 |
172 scoped_refptr<base::RefCountedBytes> png( | 192 scoped_refptr<base::RefCountedBytes> png( |
173 new base::RefCountedBytes( | 193 new base::RefCountedBytes( |
174 std::vector<unsigned char>( | 194 std::vector<unsigned char>( |
175 k1x3BlueWhite, | 195 k1x3BlueWhite, |
176 k1x3BlueWhite + sizeof(k1x3BlueWhite) / sizeof(unsigned char)))); | 196 k1x3BlueWhite + sizeof(k1x3BlueWhite) / sizeof(unsigned char)))); |
177 | 197 |
178 SkColor color = CalculateKMeanColorOfPNG(png, 100, 600, &test_sampler); | 198 SkColor color = CalculateKMeanColorOfPNG( |
| 199 png, kDefaultLowerBound, kDefaultUpperBound, &test_sampler); |
179 | 200 |
180 EXPECT_EQ(color, SkColorSetARGB(0xFF, 0x00, 0x00, 0xFF)); | 201 EXPECT_EQ(SkColorSetARGB(0xFF, 0x00, 0x00, 0xFF), color); |
181 } | 202 } |
182 | 203 |
183 TEST_F(ColorAnalysisTest, CalculatePNGKMeanPickMostCommon) { | 204 TEST_F(ColorAnalysisTest, CalculatePNGKMeanPickMostCommon) { |
184 MockKMeanImageSampler test_sampler; | 205 MockKMeanImageSampler test_sampler; |
185 test_sampler.AddSample(0); | 206 test_sampler.AddSample(0); |
186 test_sampler.AddSample(1); | 207 test_sampler.AddSample(1); |
187 test_sampler.AddSample(2); | 208 test_sampler.AddSample(2); |
188 | 209 |
189 scoped_refptr<base::RefCountedBytes> png( | 210 scoped_refptr<base::RefCountedBytes> png( |
190 new base::RefCountedBytes( | 211 new base::RefCountedBytes( |
191 std::vector<unsigned char>( | 212 std::vector<unsigned char>( |
192 k1x3BlueRed, | 213 k1x3BlueRed, |
193 k1x3BlueRed + sizeof(k1x3BlueRed) / sizeof(unsigned char)))); | 214 k1x3BlueRed + sizeof(k1x3BlueRed) / sizeof(unsigned char)))); |
194 | 215 |
195 SkColor color = CalculateKMeanColorOfPNG(png, 100, 600, &test_sampler); | 216 SkColor color = CalculateKMeanColorOfPNG( |
| 217 png, kDefaultLowerBound, kDefaultUpperBound, &test_sampler); |
196 | 218 |
197 EXPECT_EQ(color, SkColorSetARGB(0xFF, 0xFF, 0x00, 0x00)); | 219 EXPECT_EQ(SkColorSetARGB(0xFF, 0xFF, 0x00, 0x00), color); |
| 220 } |
| 221 |
| 222 TEST_F(ColorAnalysisTest, CalculatePNGKMeanIgnoreRedHue) { |
| 223 MockKMeanImageSampler test_sampler; |
| 224 test_sampler.AddSample(0); |
| 225 test_sampler.AddSample(1); |
| 226 test_sampler.AddSample(2); |
| 227 |
| 228 std::vector<SkColor> colors(4, SK_ColorRED); |
| 229 colors[1] = SK_ColorBLUE; |
| 230 |
| 231 scoped_refptr<base::RefCountedMemory> png = CreateTestPNG(colors); |
| 232 |
| 233 SkColor color = CalculateKMeanColorOfPNG( |
| 234 png, HSL{0.2, -1, 0.15}, HSL{0.8, -1, 0.85}, &test_sampler); |
| 235 |
| 236 EXPECT_EQ(SK_ColorBLUE, color); |
| 237 } |
| 238 |
| 239 TEST_F(ColorAnalysisTest, CalculatePNGKMeanIgnoreGreySaturation) { |
| 240 MockKMeanImageSampler test_sampler; |
| 241 test_sampler.AddSample(0); |
| 242 test_sampler.AddSample(1); |
| 243 test_sampler.AddSample(2); |
| 244 |
| 245 std::vector<SkColor> colors(4, SK_ColorGRAY); |
| 246 colors[1] = SK_ColorBLUE; |
| 247 |
| 248 scoped_refptr<base::RefCountedMemory> png = CreateTestPNG(colors); |
| 249 SkColor color = CalculateKMeanColorOfPNG( |
| 250 png, HSL{-1, 0.3, -1}, HSL{-1, 1, -1}, &test_sampler); |
| 251 |
| 252 EXPECT_EQ(SK_ColorBLUE, color); |
198 } | 253 } |
199 | 254 |
200 TEST_F(ColorAnalysisTest, GridSampler) { | 255 TEST_F(ColorAnalysisTest, GridSampler) { |
201 GridSampler sampler; | 256 GridSampler sampler; |
202 const int kWidth = 16; | 257 const int kWidth = 16; |
203 const int kHeight = 16; | 258 const int kHeight = 16; |
204 // Sample starts at 1,1. | 259 // Sample starts at 1,1. |
205 EXPECT_EQ(1 + 1 * kWidth, sampler.GetSample(kWidth, kHeight)); | 260 EXPECT_EQ(1 + 1 * kWidth, sampler.GetSample(kWidth, kHeight)); |
206 EXPECT_EQ(1 + 4 * kWidth, sampler.GetSample(kWidth, kHeight)); | 261 EXPECT_EQ(1 + 4 * kWidth, sampler.GetSample(kWidth, kHeight)); |
207 EXPECT_EQ(1 + 7 * kWidth, sampler.GetSample(kWidth, kHeight)); | 262 EXPECT_EQ(1 + 7 * kWidth, sampler.GetSample(kWidth, kHeight)); |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
447 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); | 502 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); |
448 | 503 |
449 EXPECT_EQ(0, min_gl); | 504 EXPECT_EQ(0, min_gl); |
450 EXPECT_EQ(255, max_gl); | 505 EXPECT_EQ(255, max_gl); |
451 EXPECT_EQ(min_gl, SkColorGetA(result.getColor(0, 0))); | 506 EXPECT_EQ(min_gl, SkColorGetA(result.getColor(0, 0))); |
452 EXPECT_EQ(max_gl, SkColorGetA(result.getColor(299, 199))); | 507 EXPECT_EQ(max_gl, SkColorGetA(result.getColor(299, 199))); |
453 EXPECT_EQ(93U, SkColorGetA(result.getColor(150, 0))); | 508 EXPECT_EQ(93U, SkColorGetA(result.getColor(150, 0))); |
454 } | 509 } |
455 | 510 |
456 } // namespace color_utils | 511 } // namespace color_utils |
OLD | NEW |