Chromium Code Reviews| 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 <limits.h> | 7 #include <limits.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 361 const HSL& lower_bound, | 361 const HSL& lower_bound, |
| 362 const HSL& upper_bound, | 362 const HSL& upper_bound, |
| 363 const HSL& goal) { | 363 const HSL& goal) { |
| 364 DCHECK(!bitmap.empty()); | 364 DCHECK(!bitmap.empty()); |
| 365 DCHECK(!bitmap.isNull()); | 365 DCHECK(!bitmap.isNull()); |
| 366 | 366 |
| 367 SkAutoLockPixels auto_lock(bitmap); | 367 SkAutoLockPixels auto_lock(bitmap); |
| 368 const uint32_t* pixels = static_cast<uint32_t*>(bitmap.getPixels()); | 368 const uint32_t* pixels = static_cast<uint32_t*>(bitmap.getPixels()); |
| 369 const int pixel_count = bitmap.width() * bitmap.height(); | 369 const int pixel_count = bitmap.width() * bitmap.height(); |
| 370 | 370 |
| 371 // We don't know exactly how many distinct colors there will be, so just | 371 // For better performance, only consider at most 10k pixels (evenly |
| 372 // reserve enough space to keep the maximum number of table resizes low. | 372 // distributed throughout the image). This has a very minor impact on the |
| 373 // In our testing set, 2/3 of wallpapers have <200k unique colors and 1/4 | 373 // outcome but improves runtime substantially for large images. 10,007 is a |
| 374 // have <100k. Thus 200k is picked as a number that usually amounts to zero | 374 // prime number to reduce the chance of picking an unrepresentative sample. |
|
James Cook
2017/04/07 14:05:47
Good idea.
Nico
2017/04/07 15:33:22
I'm too dense to understand why the divisor being
| |
| 375 // resizes but usually doesn't waste a lot of space. | 375 constexpr int kMaxConsideredPixels = 10007; |
| 376 std::unordered_map<SkColor, int> color_counts(200000); | 376 const int pixel_increment = std::max(1, pixel_count / kMaxConsideredPixels); |
| 377 std::unordered_map<SkColor, int> color_counts(kMaxConsideredPixels); | |
| 377 | 378 |
| 378 // First extract all colors into counts. | 379 // First extract all colors into counts. |
| 379 for (int i = 0; i < pixel_count; ++i) { | 380 for (int i = 0; i < pixel_count; i += pixel_increment) { |
| 380 // SkBitmap uses pre-multiplied alpha but the prominent color algorithm | 381 // SkBitmap uses pre-multiplied alpha but the prominent color algorithm |
| 381 // needs non-pre-multiplied alpha. | 382 // needs non-pre-multiplied alpha. |
| 382 const SkColor pixel = SkUnPreMultiply::PMColorToColor(pixels[i]); | 383 const SkColor pixel = SkUnPreMultiply::PMColorToColor(pixels[i]); |
| 383 if (SkColorGetA(pixel) == SK_AlphaTRANSPARENT) | 384 if (SkColorGetA(pixel) == SK_AlphaTRANSPARENT) |
| 384 continue; | 385 continue; |
| 385 | 386 |
| 386 color_counts[pixel]++; | 387 color_counts[pixel]++; |
| 387 } | 388 } |
| 388 | 389 |
| 389 // Now throw out some uninteresting colors. | 390 // Now throw out some uninteresting colors. |
| (...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 937 gfx::Matrix3F covariance = ComputeColorCovariance(source_bitmap); | 938 gfx::Matrix3F covariance = ComputeColorCovariance(source_bitmap); |
| 938 gfx::Matrix3F eigenvectors = gfx::Matrix3F::Zeros(); | 939 gfx::Matrix3F eigenvectors = gfx::Matrix3F::Zeros(); |
| 939 gfx::Vector3dF eigenvals = covariance.SolveEigenproblem(&eigenvectors); | 940 gfx::Vector3dF eigenvals = covariance.SolveEigenproblem(&eigenvectors); |
| 940 gfx::Vector3dF principal = eigenvectors.get_column(0); | 941 gfx::Vector3dF principal = eigenvectors.get_column(0); |
| 941 if (eigenvals == gfx::Vector3dF() || principal == gfx::Vector3dF()) | 942 if (eigenvals == gfx::Vector3dF() || principal == gfx::Vector3dF()) |
| 942 return false; // This may happen for some edge cases. | 943 return false; // This may happen for some edge cases. |
| 943 return ApplyColorReduction(source_bitmap, principal, true, target_bitmap); | 944 return ApplyColorReduction(source_bitmap, principal, true, target_bitmap); |
| 944 } | 945 } |
| 945 | 946 |
| 946 } // color_utils | 947 } // color_utils |
| OLD | NEW |