Index: chrome/browser/extensions/extension_tabs_module.cc =================================================================== --- chrome/browser/extensions/extension_tabs_module.cc (revision 39038) +++ chrome/browser/extensions/extension_tabs_module.cc (working copy) @@ -5,6 +5,7 @@ #include "chrome/browser/extensions/extension_tabs_module.h" #include "app/gfx/codec/jpeg_codec.h" +#include "app/gfx/codec/png_codec.h" #include "base/base64.h" #include "base/string_util.h" #include "chrome/browser/browser.h" @@ -734,11 +735,42 @@ Browser* browser; // windowId defaults to "current" window. int window_id = -1; + quality_ = 90; + image_format_ = IMAGE_JPEG; if (!args_->IsType(Value::TYPE_NULL)) { - EXTENSION_FUNCTION_VALIDATE(args_->GetAsInteger(&window_id)); + if (args_->IsType(Value::TYPE_INTEGER)) { + args_->GetAsInteger(&window_id); + } else if (args_->IsType(Value::TYPE_DICTIONARY)) { + const DictionaryValue* params = args_as_dictionary(); + if (params->HasKey(keys::kWindowIdKey)) { + EXTENSION_FUNCTION_VALIDATE(params->GetInteger( + keys::kWindowIdKey, + &window_id)); + } + if (params->HasKey(keys::kQualityKey)) { + EXTENSION_FUNCTION_VALIDATE(params->GetInteger( + keys::kQualityKey, + &quality_)); + } + if (params->HasKey(keys::kFormatKey)) { + std::string format; + EXTENSION_FUNCTION_VALIDATE(params->GetString( + keys::kFormatKey, + &format)); + if (!format.compare(keys::kFormatValueJpeg) ) { + image_format_ = IMAGE_JPEG; + } else if (!format.compare(keys::kFormatValuePng) ) { + image_format_ = IMAGE_PNG; + } else { + error_ = keys::kNotSuuportedFormatError; + return false; + } + } + } browser = GetBrowserInProfileWithId(profile(), window_id, &error_); - } else { + } + if ( window_id == -1 ) { browser = dispatcher()->GetBrowser(); } @@ -822,14 +854,26 @@ // and call SendResponse(). void CaptureVisibleTabFunction::SendResultFromBitmap( const SkBitmap& screen_capture) { - scoped_refptr jpeg_data(new RefCountedBytes); + scoped_refptr bitmap_data(new RefCountedBytes); SkAutoLockPixels screen_capture_lock(screen_capture); - bool encoded = gfx::JPEGCodec::Encode( - reinterpret_cast(screen_capture.getAddr32(0, 0)), - gfx::JPEGCodec::FORMAT_BGRA, screen_capture.width(), - screen_capture.height(), - static_cast(screen_capture.rowBytes()), 90, - &jpeg_data->data); + bool encoded = false; + if (IMAGE_JPEG == image_format_) { + encoded = gfx::JPEGCodec::Encode( + reinterpret_cast(screen_capture.getAddr32(0, 0)), + gfx::JPEGCodec::FORMAT_BGRA, screen_capture.width(), + screen_capture.height(), + static_cast(screen_capture.rowBytes()), quality_, + &bitmap_data->data); + } else if (IMAGE_PNG == image_format_) { + encoded = gfx::PNGCodec::Encode( + reinterpret_cast(screen_capture.getAddr32(0, 0)), + gfx::PNGCodec::FORMAT_BGRA, screen_capture.width(), + screen_capture.height(), + static_cast(screen_capture.rowBytes()), false, + &bitmap_data->data); + } else { + NOTREACHED(); + } if (!encoded) { error_ = ExtensionErrorUtils::FormatErrorMessage( keys::kInternalVisibleTabCaptureError, ""); @@ -839,13 +883,16 @@ std::string base64_result; std::string stream_as_string; - stream_as_string.resize(jpeg_data->data.size()); + stream_as_string.resize(bitmap_data->data.size()); memcpy(&stream_as_string[0], - reinterpret_cast(&jpeg_data->data[0]), - jpeg_data->data.size()); + reinterpret_cast(&bitmap_data->data[0]), + bitmap_data->data.size()); base::Base64Encode(stream_as_string, &base64_result); - base64_result.insert(0, "data:image/jpg;base64,"); + const char* mime_subtypes[] = {keys::kFormatValueJpeg, keys::kFormatValuePng}; + std::string mime = "data:image/"; + mime = mime + mime_subtypes[image_format_] + ";base64,"; + base64_result.insert(0, mime.c_str()); result_.reset(new StringValue(base64_result)); SendResponse(true); } Index: chrome/browser/extensions/extension_tabs_module.h =================================================================== --- chrome/browser/extensions/extension_tabs_module.h (revision 39038) +++ chrome/browser/extensions/extension_tabs_module.h (working copy) @@ -141,6 +141,10 @@ public NotificationObserver { private: ~CaptureVisibleTabFunction() {} + enum ImageFormat { + IMAGE_JPEG, + IMAGE_PNG + }; virtual bool RunImpl(); virtual void CaptureSnapshotFromBackingStore(BackingStore* backing_store); virtual void Observe(NotificationType type, @@ -149,6 +153,8 @@ virtual void SendResultFromBitmap(const SkBitmap& screen_capture); NotificationRegistrar registrar_; + ImageFormat image_format_; + int quality_; DECLARE_EXTENSION_FUNCTION_NAME("tabs.captureVisibleTab") }; Index: chrome/browser/extensions/extension_tabs_module_constants.cc =================================================================== --- chrome/browser/extensions/extension_tabs_module_constants.cc (revision 39038) +++ chrome/browser/extensions/extension_tabs_module_constants.cc (working copy) @@ -11,6 +11,7 @@ const wchar_t kFavIconUrlKey[] = L"favIconUrl"; const wchar_t kFileKey[] = L"file"; const wchar_t kFocusedKey[] = L"focused"; +const wchar_t kFormatKey[] = L"format"; const wchar_t kFromIndexKey[] = L"fromIndex"; const wchar_t kHeightKey[] = L"height"; const wchar_t kIdKey[] = L"id"; @@ -21,6 +22,7 @@ const wchar_t kOldPositionKey[] = L"oldPosition"; const wchar_t kOldWindowIdKey[] = L"oldWindowId"; const wchar_t kPopulateKey[] = L"populate"; +const wchar_t kQualityKey[] = L"quality"; const wchar_t kSelectedKey[] = L"selected"; const wchar_t kStatusKey[] = L"status"; const wchar_t kTabIdKey[] = L"tabId"; @@ -33,6 +35,9 @@ const wchar_t kWidthKey[] = L"width"; const wchar_t kWindowIdKey[] = L"windowId"; +const char kFormatValueJpeg[] = "jpeg"; +const char kFormatValuePng[] = "png"; + const char kStatusValueComplete[] = "complete"; const char kStatusValueLoading[] = "loading"; @@ -55,6 +60,7 @@ const char kMoreThanOneValuesError[] = "Code and file should not be specified " "at the same time in the second argument."; const char kLoadFileError[] = "Failed to load file: \"*\". "; +const char kNotSuuportedFormatError[] = "Not supported image format"; const char kCannotUpdatePinnedTab[] = "Cannot update pinned tabs"; const char kCannotRemovePhantomTab[] = "Cannot remove phantom tabs"; const char kCannotDetermineLanguageOfUnloadedTab[] = Index: chrome/browser/extensions/extension_tabs_module_constants.h =================================================================== --- chrome/browser/extensions/extension_tabs_module_constants.h (revision 39038) +++ chrome/browser/extensions/extension_tabs_module_constants.h (working copy) @@ -15,6 +15,7 @@ extern const wchar_t kFavIconUrlKey[]; extern const wchar_t kFileKey[]; extern const wchar_t kFocusedKey[]; +extern const wchar_t kFormatKey[]; extern const wchar_t kFromIndexKey[]; extern const wchar_t kHeightKey[]; extern const wchar_t kIdKey[]; @@ -25,6 +26,7 @@ extern const wchar_t kOldPositionKey[]; extern const wchar_t kOldWindowIdKey[]; extern const wchar_t kPopulateKey[]; +extern const wchar_t kQualityKey[]; extern const wchar_t kSelectedKey[]; extern const wchar_t kStatusKey[]; extern const wchar_t kTabIdKey[]; @@ -38,6 +40,9 @@ extern const wchar_t kWindowIdKey[]; // Value consts. +extern const char kFormatValueJpeg[]; +extern const char kFormatValuePng[]; + extern const char kStatusValueComplete[]; extern const char kStatusValueLoading[]; @@ -57,6 +62,7 @@ extern const char kNoCodeOrFileToExecuteError[]; extern const char kMoreThanOneValuesError[]; extern const char kLoadFileError[]; +extern const char kNotSuuportedFormatError[]; extern const char kCannotUpdatePinnedTab[]; extern const char kCannotRemovePhantomTab[]; extern const char kCannotDetermineLanguageOfUnloadedTab[]; Index: chrome/common/extensions/api/extension_api.json =================================================================== --- chrome/common/extensions/api/extension_api.json (revision 39038) +++ chrome/common/extensions/api/extension_api.json (working copy) @@ -875,11 +875,27 @@ "description": "Captures the visible area of the currently selected tab in the specified window.", "parameters": [ { - "type": "integer", - "name": "windowId", - "minimum": 0, - "optional": true, - "description": "The target window. Defaults to the current window." + "name": "windowIdOrParams", + "choices": [ + { + "type": "integer", + "name": "windowId", + "minimum": 0, + "optional": true, + "description": "The target window. Defaults to the current window." + }, + { + "type": "object", + "name": "params", + "optional": true, + "properties": { + "windowId": {"type": "integer", "optional": true, "minimum": 0, "description": "The target window. Defaults to the current window."}, + "format": {"type": "string", "optional": true, "description": "The image format of capture. Defaults to jpeg. Available formats are: jpeg and png."}, + "quality": {"type": "integer", "optional": true, "maximum": 100, "description":"Quality of capture. Effective only when format is jpeg."} + }, + "description": "Parameters to control details of capture." + } + ] }, { "type": "function", "name": "callback", "parameters": [