UIActivityViewController 复制忽略 imageOrientation

Posted

技术标签:

【中文标题】UIActivityViewController 复制忽略 imageOrientation【英文标题】:UIActivityViewController Copy Ignores imageOrientation 【发布时间】:2015-01-13 04:56:02 【问题描述】:

当我在人像模式下使用手机拍照时,使用 UIImagePickerController,返回的 UIImage 项的图像顶部朝左,imageOrientation 属性为UIImageOrientationRight , // 90 deg CCW,这与预期的一样(我认为) .

当我通过 UIActivityViewController 共享图像时,所有活动似乎都正常运行,除了 Copy 活动。当我将图像粘贴到另一个应用程序(例如 Messages)时,图像似乎忽略了 imageOrientation 属性。

有其他人看到这个/找到解决方法吗?

已更新完整代码:(项目包含带有映射到self.takeImageButton- (IBAction)takeImageAndShare:(id)sender; 的单个按钮的情节提要)

#import "ViewController.h"

@interface ViewController () <UIImagePickerControllerDelegate,UINavigationControllerDelegate>

@property (weak, nonatomic) IBOutlet UIButton *takeImageButton;

@end

@implementation ViewController

- (void)viewDidLoad 
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.


- (void)didReceiveMemoryWarning 
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.


- (IBAction)takeImageAndShare:(id)sender 
    UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
    imagePicker.delegate = self;
    imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
    imagePicker.popoverPresentationController.sourceView = self.takeImageButton;
    [self presentViewController:imagePicker animated:YES completion:nil];


- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info

    UIImage *chosenImage = info[UIImagePickerControllerOriginalImage];
    [picker dismissViewControllerAnimated:YES completion:NULL];

    NSLog(@"Image Orientation: %li",chosenImage.imageOrientation);

    // Now share the selected image
    UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:@[chosenImage] applicationActivities:nil];
    activityViewController.modalPresentationStyle = UIModalPresentationPopover;
    activityViewController.popoverPresentationController.sourceView = self.takeImageButton;
    [self presentViewController:activityViewController animated:YES completion:nil];


- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker;

    [picker dismissViewControllerAnimated:YES completion:NULL];


@end

如果您运行此代码,请用手机纵向拍照(.imageOrientation 为 3 = UIImageOrientationRight)并选择消息、保存图像等分享活动,图像方向正确。如果您选择复制活动,则粘贴到别处的图像会旋转(图像的顶部在左侧)。

以Radar 19456881 提交。完整的项目可用here。

【问题讨论】:

【参考方案1】:

默认捕捉图像方向行为是UIImageOrientationRight,sp你必须设置捕捉图像方向是

[UIDevice currentDevice].orientation

【讨论】:

由于 imageOrientation 被定义为只读 (@property(nonatomic, readonly) UIImageOrientation imageOrientation),您将在哪里捕获方向?此外,似乎通过 UIActivityViewController 可用的所有其他活动都尊重 imageOrientation 属性,因此修改该属性会导致其他活动行为不端。 @JeffV 用于根据设备方向捕获图像,您必须为此设置捕获图像方向,否则默认情况下它将是 UIImageOrientationRight 并使用上面的只读属性,我们可以在捕获时获取当前设备方向我们设置通知系统将在设备中保存的方向图像。【参考方案2】:

根据this 的帖子,我决定创建自己的复制活动:

//
//  PhotoActivityCopy.m
//
//  Created by Jeff Vautin on 1/13/15.
//  Copyright (c) 2015 Jeff Vautin. All rights reserved.
//

#import "PhotoActivityCopy.h"
#import "ImageKit.h"
@import MobileCoreServices;

@interface PhotoActivityCopy ()

@property (strong,nonatomic) NSData *imageJPEGData;

@end

@implementation PhotoActivityCopy

NSString *PhotoActivityCopyActivityType = @"com.me.uiactivitytype.copy";
NSString *PhotoActivityCopyActivityTitle = @"Copy";

+ (UIActivityCategory)activityCategory

    return UIActivityCategoryAction;


- (NSString *)activityType

    return PhotoActivityCopyActivityType;


- (NSString *)activityTitle

    return PhotoActivityCopyActivityTitle;


- (UIImage *)activityImage

    CGSize imageSize;
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) 
        imageSize = CGSizeMake(76.0, 76.0);
     else 
        imageSize = CGSizeMake(60.0, 60.0);
    

    return [ImageKit imageOfIconCopyWithExportSize:imageSize];


- (BOOL)canPerformWithActivityItems:(NSArray *)activityItems

    BOOL canPerform = NO;

    if ([activityItems count] > 1) 
        canPerform = NO;
     else if ([[activityItems firstObject] isKindOfClass:[UIImage class]]) 
        canPerform = YES;
    

    return canPerform;


- (void)prepareWithActivityItems:(NSArray *)activityItems

    self.imageJPEGData = UIImageJPEGRepresentation(activityItems[0], 1.0);


- (void)performActivity

    [[UIPasteboard generalPasteboard] setData:self.imageJPEGData forPasteboardType:(id)kUTTypeJPEG];
    [self activityDidFinish:YES];


@end

然后我排除了本机复制活动:

PhotoActivityCopy *copyActivity = [[PhotoActivityCopy alloc] init];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:@[chosenImage] applicationActivities:@[copyActivity]];
activityViewController.excludedActivityTypes = @[UIActivityTypeCopyToPasteboard];

【讨论】:

以上是关于UIActivityViewController 复制忽略 imageOrientation的主要内容,如果未能解决你的问题,请参考以下文章

UIActivityViewController 背景颜色

UIActivityViewController 共享 UIActivity 未显示

UIActivityViewController 不适用于 WKWebView

限制 UIActivityViewController 共享扩展活动

尝试呈现 UIActivityViewController 时崩溃

更改 UIActivityViewController 的 navigationBar 的颜色