Commit c2d8756e authored by Yi Su's avatar Yi Su Committed by Commit Bot

Copy both the image's url and data to pasteboard when CopyImage.

Current CopyImage only copies the image data to pasteboard. Image's url
should also be copied, so that user can paste it to text field.

Bug: 883674
Cq-Include-Trybots: luci.chromium.try:ios-simulator-cronet;luci.chromium.try:ios-simulator-full-configs
Change-Id: I30c9bd1018a5a2e4564b9bc7a40d69be325a4235
Reviewed-on: https://chromium-review.googlesource.com/1228061
Commit-Queue: Yi Su <mrsuyi@chromium.org>
Reviewed-by: default avatarGauthier Ambard <gambard@chromium.org>
Cr-Commit-Position: refs/heads/master@{#592012}
parent 8566083c
...@@ -4,9 +4,13 @@ ...@@ -4,9 +4,13 @@
#import "image_copier.h" #import "image_copier.h"
#include <MobileCoreServices/MobileCoreServices.h>
#import "base/strings/sys_string_conversions.h"
#include "base/task/post_task.h" #include "base/task/post_task.h"
#include "components/strings/grit/components_strings.h" #include "components/strings/grit/components_strings.h"
#import "ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h" #import "ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h"
#import "ios/chrome/browser/ui/image_util/image_util.h"
#import "ios/chrome/browser/web/image_fetch_tab_helper.h" #import "ios/chrome/browser/web/image_fetch_tab_helper.h"
#include "ios/chrome/grit/ios_strings.h" #include "ios/chrome/grit/ios_strings.h"
#include "ios/web/public/web_task_traits.h" #include "ios/web/public/web_task_traits.h"
...@@ -61,7 +65,7 @@ const int kNoActiveCopy = 0; ...@@ -61,7 +65,7 @@ const int kNoActiveCopy = 0;
- (void)copyImageAtURL:(const GURL&)url - (void)copyImageAtURL:(const GURL&)url
referrer:(const web::Referrer&)referrer referrer:(const web::Referrer&)referrer
webState:(web::WebState*)webState { webState:(web::WebState*)webState {
// Dismisses current alert. // Dismiss current alert.
[self.alertCoordinator stop]; [self.alertCoordinator stop];
__weak ImageCopier* weakSelf = self; __weak ImageCopier* weakSelf = self;
...@@ -74,7 +78,7 @@ const int kNoActiveCopy = 0; ...@@ -74,7 +78,7 @@ const int kNoActiveCopy = 0;
[self.alertCoordinator [self.alertCoordinator
addItemWithTitle:l10n_util::GetNSStringWithFixup(IDS_CANCEL) addItemWithTitle:l10n_util::GetNSStringWithFixup(IDS_CANCEL)
action:^() { action:^() {
// Cancels current copy and closes the alert. // Cancel current copy and closes the alert.
weakSelf.activeID = kNoActiveCopy; weakSelf.activeID = kNoActiveCopy;
[weakSelf.alertCoordinator stop]; [weakSelf.alertCoordinator stop];
} }
...@@ -93,20 +97,27 @@ const int kNoActiveCopy = 0; ...@@ -93,20 +97,27 @@ const int kNoActiveCopy = 0;
ImageFetchTabHelper* tabHelper = ImageFetchTabHelper::FromWebState(webState); ImageFetchTabHelper* tabHelper = ImageFetchTabHelper::FromWebState(webState);
DCHECK(tabHelper); DCHECK(tabHelper);
NSString* urlStr = base::SysUTF8ToNSString(url.spec());
tabHelper->GetImageData(url, referrer, ^(NSData* data) { tabHelper->GetImageData(url, referrer, ^(NSData* data) {
// Checks that the copy has not been canceled. // Check that the copy has not been canceled.
if (callbackID == weakSelf.activeID) { if (callbackID == weakSelf.activeID) {
UIImage* image = [UIImage imageWithData:data]; NSMutableDictionary* item =
if (image) { [NSMutableDictionary dictionaryWithCapacity:3];
UIPasteboard.generalPasteboard.image = image; [item setValue:urlStr forKey:(__bridge NSString*)kUTTypeText];
} [item setValue:[NSURL URLWithString:urlStr]
forKey:(__bridge NSString*)kUTTypeURL];
NSString* uti = GetImageUTIFromData(data);
if (uti)
[item setValue:data forKey:uti];
UIPasteboard.generalPasteboard.items =
[NSMutableArray arrayWithObject:item];
// Finishes this copy. // Finishes this copy.
weakSelf.activeID = kNoActiveCopy; weakSelf.activeID = kNoActiveCopy;
[weakSelf.alertCoordinator stop]; [weakSelf.alertCoordinator stop];
} }
}); });
// Delays launching alert by |kAlertDelayInMs|. // Delay launching alert by |kAlertDelayInMs|.
base::PostDelayedTaskWithTraits( base::PostDelayedTaskWithTraits(
FROM_HERE, {web::WebThread::UI}, base::BindOnce(^{ FROM_HERE, {web::WebThread::UI}, base::BindOnce(^{
// Checks that the copy has not finished yet. // Checks that the copy has not finished yet.
......
...@@ -35,4 +35,8 @@ UIImage* StretchableImageNamed(NSString* name, ...@@ -35,4 +35,8 @@ UIImage* StretchableImageNamed(NSString* name,
// is nil, empty, or cannot be recognized, nil will be returned. // is nil, empty, or cannot be recognized, nil will be returned.
NSString* GetImageExtensionFromData(NSData* data); NSString* GetImageExtensionFromData(NSData* data);
// Returns the UTI by checking the first byte of image |data|. If |data|
// is nil, empty, or cannot be recognized, nil will be returned.
NSString* GetImageUTIFromData(NSData* data);
#endif // IOS_CHROME_BROWSER_UI_IMAGE_UTIL_IMAGE_UTIL_H_ #endif // IOS_CHROME_BROWSER_UI_IMAGE_UTIL_IMAGE_UTIL_H_
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#import <MobileCoreServices/MobileCoreServices.h>
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import "ios/chrome/browser/ui/image_util/image_util.h" #import "ios/chrome/browser/ui/image_util/image_util.h"
...@@ -13,6 +14,16 @@ ...@@ -13,6 +14,16 @@
#error "This file requires ARC support." #error "This file requires ARC support."
#endif #endif
namespace {
NSString* kImageExtensionJPG = @"jpg";
NSString* kImageExtensionPNG = @"png";
NSString* kImageExtensionTIF = @"tif";
NSString* kImageExtensionBMP = @"bmp";
NSString* kImageExtensionGIF = @"gif";
NSString* kImageExtensionICO = @"ico";
NSString* kImageExtensionWebP = @"webp";
}
UIColor* DominantColorForImage(const gfx::Image& image, CGFloat opacity) { UIColor* DominantColorForImage(const gfx::Image& image, CGFloat opacity) {
SkColor color = color_utils::CalculateKMeanColorOfBitmap(*image.ToSkBitmap()); SkColor color = color_utils::CalculateKMeanColorOfBitmap(*image.ToSkBitmap());
UIColor* result = [UIColor colorWithRed:SkColorGetR(color) / 255.0 UIColor* result = [UIColor colorWithRed:SkColorGetR(color) / 255.0
...@@ -58,28 +69,41 @@ NSString* GetImageExtensionFromData(NSData* data) { ...@@ -58,28 +69,41 @@ NSString* GetImageExtensionFromData(NSData* data) {
const char* pdata = static_cast<const char*>(data.bytes); const char* pdata = static_cast<const char*>(data.bytes);
switch (pdata[0]) { switch (pdata[0]) {
case '\xFF': case '\xFF':
return strncmp(pdata, "\xFF\xD8\xFF", 3) ? nil : @"jpg"; return strncmp(pdata, "\xFF\xD8\xFF", 3) ? nil : kImageExtensionJPG;
case '\x89': case '\x89':
return strncmp(pdata, "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", 8) ? nil return strncmp(pdata, "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", 8)
: @"png"; ? nil
: kImageExtensionPNG;
case 'G': case 'G':
return (strncmp(pdata, "GIF87a", 6) && strncmp(pdata, "GIF89a", 6)) return (strncmp(pdata, "GIF87a", 6) && strncmp(pdata, "GIF89a", 6))
? nil ? nil
: @"gif"; : kImageExtensionGIF;
case '\x49': case '\x49':
return strncmp(pdata, "\x49\x49\x2A\x00", 4) ? nil : @"tif"; return strncmp(pdata, "\x49\x49\x2A\x00", 4) ? nil : kImageExtensionTIF;
case '\x4D': case '\x4D':
return strncmp(pdata, "\x4D\x4D\x00\x2A", 4) ? nil : @"tif"; return strncmp(pdata, "\x4D\x4D\x00\x2A", 4) ? nil : kImageExtensionTIF;
case 'B': case 'B':
return strncmp(pdata, "BM", 2) ? nil : @"bmp"; return strncmp(pdata, "BM", 2) ? nil : kImageExtensionBMP;
case 'R': case 'R':
return (strncmp(pdata, "RIFF", 4) || strncmp(pdata + 8, "WEBP", 4)) return (strncmp(pdata, "RIFF", 4) || strncmp(pdata + 8, "WEBP", 4))
? nil ? nil
: @"webp"; : kImageExtensionWebP;
case '\0': case '\0':
return strncmp(pdata, "\x00\x00\x01\x00", 4) ? nil : @"ico"; return strncmp(pdata, "\x00\x00\x01\x00", 4) ? nil : kImageExtensionICO;
default: default:
return nil; return nil;
} }
return nil; return nil;
} }
NSString* GetImageUTIFromData(NSData* data) {
static NSDictionary* dict = @{
kImageExtensionJPG : (__bridge NSString*)kUTTypeJPEG,
kImageExtensionPNG : (__bridge NSString*)kUTTypePNG,
kImageExtensionGIF : (__bridge NSString*)kUTTypeGIF,
kImageExtensionTIF : (__bridge NSString*)kUTTypeTIFF,
kImageExtensionBMP : (__bridge NSString*)kUTTypeBMP,
kImageExtensionICO : (__bridge NSString*)kUTTypeICO
};
return dict[GetImageExtensionFromData(data)];
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment