Chromium Code Reviews| Index: chrome/browser/chromeos/login/users/avatar/user_image_loader.cc |
| diff --git a/chrome/browser/chromeos/login/users/avatar/user_image_loader.cc b/chrome/browser/chromeos/login/users/avatar/user_image_loader.cc |
| index dc0e9117a3288df849e0a1ee5c5adbfd4ee0e7e7..b50267c079ac8a0a8ca93d1c015dd885b4184d64 100644 |
| --- a/chrome/browser/chromeos/login/users/avatar/user_image_loader.cc |
| +++ b/chrome/browser/chromeos/login/users/avatar/user_image_loader.cc |
| @@ -85,8 +85,14 @@ class UserImageRequest : public ImageDecoder::ImageRequest { |
| void OnImageDecoded(const SkBitmap& decoded_image) override; |
| void OnDecodeImageFailed() override; |
| - // Called after the image is transformed (cropped and downsized) as needed. |
| - void OnImageFinalized(const SkBitmap& image); |
| + // Called after the image is cropped (and downsized) as needed. |
| + void OnImageCropped(const SkBitmap& image); |
| + |
| + // Called after the image is finalized. |image_bytes_regenerated| is true |
| + // if |image_bytes| is regenerated from the cropped image. |
| + void OnImageFinalized(const SkBitmap& image, |
| + bool image_bytes_regenerated, |
| + const user_manager::UserImage::Bytes& image_bytes); |
| private: |
| const ImageInfo image_info_; |
| @@ -100,19 +106,42 @@ class UserImageRequest : public ImageDecoder::ImageRequest { |
| void UserImageRequest::OnImageDecoded(const SkBitmap& decoded_image) { |
| int target_size = image_info_.pixels_per_side; |
| if (target_size > 0) { |
| - // Transforming an image could be expensive, hence posting to the |
| - // background thread. |
| + // Cropping an image could be expensive, hence posting to the background |
| + // thread. |
| base::PostTaskAndReplyWithResult( |
| background_task_runner_.get(), FROM_HERE, |
| base::Bind(&CropImage, decoded_image, target_size), |
| - base::Bind(&UserImageRequest::OnImageFinalized, |
| + base::Bind(&UserImageRequest::OnImageCropped, |
| weak_ptr_factory_.GetWeakPtr())); |
| } else { |
| - OnImageFinalized(decoded_image); |
| + OnImageFinalized(decoded_image, false /* image_bytes_regenerated */, |
| + image_data_); |
| } |
| } |
| -void UserImageRequest::OnImageFinalized(const SkBitmap& image) { |
| +void UserImageRequest::OnImageCropped(const SkBitmap& image) { |
| + DCHECK_GT(image_info_.pixels_per_side, 0); |
| + |
| + // Encode the cropped image to web-compatible bytes representation, because |
| + // the original data in |image_data_| isn't cropped and can be big. |
| + // Encoding could be expensive, hence posting to the background thread. |
| + base::PostTaskAndReplyWithResult( |
| + background_task_runner_.get(), FROM_HERE, |
| + base::Bind(&user_manager::UserImage::Encode, image), |
|
hashimoto
2016/03/02 07:33:58
Why don't you call Encode() from CropImage()?
IIUC
satorux1
2016/03/02 08:23:50
That's a great point. Fixed!
|
| + base::Bind(&UserImageRequest::OnImageFinalized, |
| + weak_ptr_factory_.GetWeakPtr(), image, |
| + true /* image_bytes_regenerated */)); |
| +} |
| + |
| +void UserImageRequest::OnImageFinalized( |
| + const SkBitmap& image, |
| + bool image_bytes_regenerated, |
| + const user_manager::UserImage::Bytes& image_bytes) { |
| + if (image_bytes.empty()) { // Failed to encode to bytes. |
| + OnDecodeImageFailed(); |
| + return; |
| + } |
| + |
| SkBitmap final_image = image; |
| // Make the SkBitmap immutable as we won't modify it. This is important |
| // because otherwise it gets duplicated during painting, wasting memory. |
| @@ -120,9 +149,10 @@ void UserImageRequest::OnImageFinalized(const SkBitmap& image) { |
| gfx::ImageSkia final_image_skia = |
| gfx::ImageSkia::CreateFrom1xBitmap(final_image); |
| final_image_skia.MakeThreadSafe(); |
| - user_manager::UserImage user_image(final_image_skia, image_data_); |
| + user_manager::UserImage user_image(final_image_skia, image_bytes); |
| user_image.set_file_path(image_info_.file_path); |
| - if (image_info_.image_codec == ImageDecoder::ROBUST_JPEG_CODEC) |
| + if (image_info_.image_codec == ImageDecoder::ROBUST_JPEG_CODEC || |
| + image_bytes_regenerated) |
| user_image.MarkAsSafe(); |
| image_info_.loaded_cb.Run(user_image); |
| delete this; |