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 |