1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/chromeos/login/user_image_loader.h" 6 7 #include "base/file_path.h" 8 #include "base/file_util.h" 9 #include "base/message_loop.h" 10 #include "chrome/browser/chromeos/login/image_decoder.h" 11 #include "chrome/browser/chromeos/login/helper.h" 12 #include "content/browser/browser_thread.h" 13 #include "skia/ext/image_operations.h" 14 #include "third_party/skia/include/core/SkBitmap.h" 15 #include "ui/gfx/codec/png_codec.h" 16 #include "ui/gfx/skbitmap_operations.h" 17 18 namespace chromeos { 19 20 UserImageLoader::UserImageLoader(Delegate* delegate) 21 : target_message_loop_(NULL), 22 delegate_(delegate) { 23 } 24 25 UserImageLoader::~UserImageLoader() { 26 } 27 28 void UserImageLoader::Start(const std::string& username, 29 const std::string& filename, 30 bool should_save_image) { 31 target_message_loop_ = MessageLoop::current(); 32 33 ImageInfo image_info(username, should_save_image); 34 BrowserThread::PostTask(BrowserThread::FILE, 35 FROM_HERE, 36 NewRunnableMethod(this, 37 &UserImageLoader::LoadImage, 38 filename, 39 image_info)); 40 } 41 42 void UserImageLoader::LoadImage(const std::string& filepath, 43 const ImageInfo& image_info) { 44 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 45 std::string image_data; 46 file_util::ReadFileToString(FilePath(filepath), &image_data); 47 48 scoped_refptr<ImageDecoder> image_decoder = 49 new ImageDecoder(this, image_data); 50 image_info_map_.insert(std::make_pair(image_decoder.get(), image_info)); 51 image_decoder->Start(); 52 } 53 54 void UserImageLoader::OnImageDecoded(const ImageDecoder* decoder, 55 const SkBitmap& decoded_image) { 56 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 57 ImageInfoMap::iterator info_it = image_info_map_.find(decoder); 58 if (info_it == image_info_map_.end()) { 59 NOTREACHED(); 60 return; 61 } 62 ImageInfo image_info = info_it->second; 63 SkBitmap final_image = decoded_image; 64 if (image_info.should_save_image) { 65 // Auto crop the image, taking the largest square in the center. 66 // Also make the image smaller to save space and memory. 67 int size = std::min(decoded_image.width(), decoded_image.height()); 68 int x = (decoded_image.width() - size) / 2; 69 int y = (decoded_image.height() - size) / 2; 70 SkBitmap cropped_image = 71 SkBitmapOperations::CreateTiledBitmap(decoded_image, x, y, size, size); 72 final_image = 73 skia::ImageOperations::Resize(cropped_image, 74 skia::ImageOperations::RESIZE_LANCZOS3, 75 login::kUserImageSize, 76 login::kUserImageSize); 77 } 78 target_message_loop_->PostTask(FROM_HERE, 79 NewRunnableMethod(this, 80 &UserImageLoader::NotifyDelegate, 81 final_image, 82 image_info)); 83 image_info_map_.erase(info_it); 84 } 85 86 void UserImageLoader::OnDecodeImageFailed(const ImageDecoder* decoder) { 87 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 88 image_info_map_.erase(decoder); 89 } 90 91 void UserImageLoader::NotifyDelegate(const SkBitmap& image, 92 const ImageInfo& image_info) { 93 if (delegate_) { 94 delegate_->OnImageLoaded(image_info.username, 95 image, 96 image_info.should_save_image); 97 } 98 } 99 100 } // namespace chromeos 101