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 <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
| 10 #include "base/logging.h" |
10 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
11 #include "third_party/skia/include/core/SkBitmap.h" | 12 #include "third_party/skia/include/core/SkBitmap.h" |
12 #include "third_party/skia/include/core/SkUnPreMultiply.h" | 13 #include "third_party/skia/include/core/SkUnPreMultiply.h" |
13 #include "ui/gfx/codec/png_codec.h" | 14 #include "ui/gfx/codec/png_codec.h" |
14 | 15 |
15 namespace { | 16 namespace { |
16 | 17 |
17 // RGBA KMean Constants | 18 // RGBA KMean Constants |
18 const uint32_t kNumberOfClusters = 4; | 19 const uint32_t kNumberOfClusters = 4; |
19 const int kNumberOfIterations = 50; | 20 const int kNumberOfIterations = 50; |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 SkColor color = CalculateKMeanColorOfBuffer( | 393 SkColor color = CalculateKMeanColorOfBuffer( |
393 reinterpret_cast<uint8_t*>(image.get()), | 394 reinterpret_cast<uint8_t*>(image.get()), |
394 bitmap.width(), | 395 bitmap.width(), |
395 bitmap.height(), | 396 bitmap.height(), |
396 kMinDarkness, | 397 kMinDarkness, |
397 kMaxBrightness, | 398 kMaxBrightness, |
398 &sampler); | 399 &sampler); |
399 return color; | 400 return color; |
400 } | 401 } |
401 | 402 |
| 403 gfx::Matrix3F ComputeColorCovariance(const SkBitmap& bitmap) { |
| 404 // First need basic stats to normalize each channel separately. |
| 405 SkAutoLockPixels bitmap_lock(bitmap); |
| 406 gfx::Matrix3F covariance = gfx::Matrix3F::Zeros(); |
| 407 if (!bitmap.getPixels()) |
| 408 return covariance; |
| 409 |
| 410 // Assume ARGB_8888 format. |
| 411 DCHECK(bitmap.config() == SkBitmap::kARGB_8888_Config); |
| 412 |
| 413 int64_t r_sum = 0; |
| 414 int64_t g_sum = 0; |
| 415 int64_t b_sum = 0; |
| 416 int64_t rr_sum = 0; |
| 417 int64_t gg_sum = 0; |
| 418 int64_t bb_sum = 0; |
| 419 int64_t rg_sum = 0; |
| 420 int64_t rb_sum = 0; |
| 421 int64_t gb_sum = 0; |
| 422 |
| 423 for (int y = 0; y < bitmap.height(); ++y) { |
| 424 SkPMColor* current_color = static_cast<uint32_t*>(bitmap.getAddr32(0, y)); |
| 425 for (int x = 0; x < bitmap.width(); ++x, ++current_color) { |
| 426 SkColor c = SkUnPreMultiply::PMColorToColor(*current_color); |
| 427 SkColor r = SkColorGetR(c); |
| 428 SkColor g = SkColorGetG(c); |
| 429 SkColor b = SkColorGetB(c); |
| 430 |
| 431 r_sum += r; |
| 432 g_sum += g; |
| 433 b_sum += b; |
| 434 rr_sum += r * r; |
| 435 gg_sum += g * g; |
| 436 bb_sum += b * b; |
| 437 rg_sum += r * g; |
| 438 rb_sum += r * b; |
| 439 gb_sum += g * b; |
| 440 } |
| 441 } |
| 442 |
| 443 // Covariance (not normalized) is E(X*X.t) - m * m.t and this is how it |
| 444 // is calculated below. |
| 445 // Each row below represents a row of the matrix describing (co)variances |
| 446 // of R, G and B channels with (R, G, B) |
| 447 int pixel_n = bitmap.width() * bitmap.height(); |
| 448 covariance.set( |
| 449 (static_cast<double>(rr_sum) / pixel_n - |
| 450 static_cast<double>(r_sum * r_sum) / pixel_n / pixel_n), |
| 451 (static_cast<double>(rg_sum) / pixel_n - |
| 452 static_cast<double>(r_sum * g_sum) / pixel_n / pixel_n), |
| 453 (static_cast<double>(rb_sum) / pixel_n - |
| 454 static_cast<double>(r_sum * b_sum) / pixel_n / pixel_n), |
| 455 (static_cast<double>(rg_sum) / pixel_n - |
| 456 static_cast<double>(r_sum * g_sum) / pixel_n / pixel_n), |
| 457 (static_cast<double>(gg_sum) / pixel_n - |
| 458 static_cast<double>(g_sum * g_sum) / pixel_n / pixel_n), |
| 459 (static_cast<double>(gb_sum) / pixel_n - |
| 460 static_cast<double>(g_sum * b_sum) / pixel_n / pixel_n), |
| 461 (static_cast<double>(rb_sum) / pixel_n - |
| 462 static_cast<double>(r_sum * b_sum) / pixel_n / pixel_n), |
| 463 (static_cast<double>(gb_sum) / pixel_n - |
| 464 static_cast<double>(g_sum * b_sum) / pixel_n / pixel_n), |
| 465 (static_cast<double>(bb_sum) / pixel_n - |
| 466 static_cast<double>(b_sum * b_sum) / pixel_n / pixel_n)); |
| 467 return covariance; |
| 468 } |
| 469 |
402 } // color_utils | 470 } // color_utils |
OLD | NEW |