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..f4d9530c1966d9e60c8efdb3114322ffa695c6c9 100644 |
| --- a/chrome/browser/chromeos/login/users/avatar/user_image_loader.cc |
| +++ b/chrome/browser/chromeos/login/users/avatar/user_image_loader.cc |
| @@ -44,9 +44,13 @@ struct ImageInfo { |
| const LoadedCallback loaded_cb; |
| }; |
| +typedef std::pair<SkBitmap, scoped_ptr<user_manager::UserImage::Bytes>> |
| + CropResultPair; |
| + |
| // Crops |image| to the square format and downsizes the image to |
| -// |target_size| in pixels. |
| -SkBitmap CropImage(const SkBitmap& image, int target_size) { |
| +// |target_size| in pixels. Returns the cropped image and the regenerated |
| +// bytes representation as a pair. The latter can be null on failure. |
| +CropResultPair CropImage(const SkBitmap& image, int target_size) { |
| DCHECK_GT(target_size, 0); |
| SkBitmap final_image; |
| @@ -64,7 +68,11 @@ SkBitmap CropImage(const SkBitmap& image, int target_size) { |
| } else { |
| final_image = cropped_image; |
| } |
| - return final_image; |
| + |
| + // Encode the cropped image to web-compatible bytes representation |
| + scoped_ptr<user_manager::UserImage::Bytes> bytes = |
| + user_manager::UserImage::Encode(final_image); |
| + return std::make_pair(final_image, std::move(bytes)); |
| } |
| // Handles the decoded image returned from ImageDecoder through the |
| @@ -85,8 +93,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 CropResultPair& pair); |
| + |
| + // 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, |
| + const user_manager::UserImage::Bytes& image_bytes, |
| + bool image_bytes_regenerated); |
| private: |
| const ImageInfo image_info_; |
| @@ -100,19 +114,34 @@ 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, image_data_, |
| + false /* image_bytes_regenerated */); |
| + } |
| +} |
| + |
| +void UserImageRequest::OnImageCropped(const CropResultPair& pair) { |
| + DCHECK_GT(image_info_.pixels_per_side, 0); |
| + |
| + if (!pair.second) { // Failed to encode to bytes representation. |
|
hashimoto
2016/03/04 06:39:50
Checking pair.second looks too subtle.
Could you m
satorux1
2016/03/09 08:50:40
Done.
|
| + OnDecodeImageFailed(); |
| + return; |
| } |
| + OnImageFinalized(pair.first, *pair.second, |
| + true /* image_bytes_regenerated */); |
| } |
| -void UserImageRequest::OnImageFinalized(const SkBitmap& image) { |
| +void UserImageRequest::OnImageFinalized( |
| + const SkBitmap& image, |
| + const user_manager::UserImage::Bytes& image_bytes, |
| + bool image_bytes_regenerated) { |
| 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; |