美文网首页iOS开发杂货铺IOS开发路上的故事iOS开发
使用UIImagePickerController选取图片并访问

使用UIImagePickerController选取图片并访问

作者: OlsonXia | 来源:发表于2016-06-13 19:00 被阅读9446次

    UIImagePickerController是iOS系统提供的选取相册图片和进行拍照的视图控制器,可以通过delegate的方法获取UIImage对象,进行后续操作。UIImage对象只是一个图像对象,无法从中获取图像的原始信息,比如原图数据,格式等。

    我们来看下UIImagePickerControllerDelegate中的回调方法

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

    其中info的信息给访问原始数据提供了可能。info包含的键如下

    NSString *const  UIImagePickerControllerMediaType ;指定用户选择的媒体类型(文章最后进行扩展)
    NSString *const  UIImagePickerControllerOriginalImage ;原始图片
    NSString *const  UIImagePickerControllerEditedImage ;修改后的图片
    NSString *const  UIImagePickerControllerCropRect ;裁剪尺寸
    NSString *const  UIImagePickerControllerMediaURL ;媒体的URL
    NSString *const  UIImagePickerControllerReferenceURL ;原件的URL
    NSString *const  UIImagePickerControllerMediaMetadata;当来数据来源是照相机的时候这个值才有效
    

    info中的key值
    其中UIImagePickerControllerReferenceURL是原始文件的URL,我们可以通过它来访问原始图片信息。这里需要注意的是,这个URL不是沙盒文件路径的URL,而是一个AssetURL,需要系统提供的AssetsLibrary框架进行访问。

    ALAssetsLibrary可以实现查看相册列表,增加相册,保存图片到相册等功能。它的组成比较符合照片库本身的组成,照片库中的完整照片库对象、相册、相片都能在 AssetsLibrary 中找到一一对应的组成,这使到 AssetsLibrary 的使用变得直观而方便。

    下面来看一下如何通过info信息读取原始图片的数据

    NSURL *imageAssetUrl = [info objectForKey:UIImagePickerControllerReferenceURL];
    
    ALAssetsLibrary *assetLibrary=[[ALAssetsLibrary alloc] init];
    
    [assetLibrary assetForURL:imageAssetUrl resultBlock:^(ALAsset *asset)  {
    
    ALAssetRepresentation* representation = [asset defaultRepresentation];
    
    // 创建一个buffer保存图片数据
    
    uint8_t *buffer = (Byte*)malloc(representation.size);
    
    NSUInteger length = [representation getBytes:buffer fromOffset: 0.0  length:representation.size error:nil];
    
    // 将buffer转换为NSData object,然后释放buffer内存
    
    NSData *imageData = [[NSData alloc] initWithBytesNoCopy:buffer length:representation.size freeWhenDone:YES];
    
    } failureBlock:^(NSError *error) {
    
    //失败的处理
    
    }];
    

    这里需要注意的是,读取图片的信息是一个异步操作。

    在iOS8以后,苹果提供一套全新的框架PhotoKit来代替ALAssetsLibrary。PhotoKit 是一套比 AssetsLibrary 更完整也更高效的库,对资源的处理跟 AssetsLibrary 也有很大的不同。

    下面再来看一下如何使用PhotoKit框架读取原始图片的数据

    NSURL *imageAssetUrl = [info objectForKey:UIImagePickerControllerReferenceURL];
    
    PHFetchResult*result = [PHAsset fetchAssetsWithALAssetURLs:@[imageAssetUrl] options:nil];
    
    PHAsset *asset = [result firstObject];
    
    PHImageRequestOptions *phImageRequestOptions = [[PHImageRequestOptions alloc] init];
    
    [[PHImageManager defaultManager] requestImageDataForAsset:asset options:phImageRequestOptions resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
    
    NSData *imageData = imageData;
    
    }];
    

    PHImageRequestOptions中可以指定请求是同步或者异步。

    对于AssetsLibrary框架和PhotoKit框架的使用想要深入了解的同学可以参考iOS 开发之照片框架详解

    以上获取原图数据的代码,可以实现类似微信发送原图的功能。

    相关文章

      网友评论

      • Lyndon_6594:你好!
        fileURL = (info[UIImagePickerControllerReferenceURL] as? URL)!
        let source = CGImageSourceCreateWithURL (fileURL! as CFURL, nil)
        let sourceProperties = CGImageSourceCopyProperties(source!, nil)
        但因为这个fileURL不是URL不是沙盒文件路径的URL,而是一个AssetURL,
        请问一下, 是否可以将AssertURL 转换成沙盒文件路径的URL, 或者是否能直接从AssetsLibrary得到source 信息?
      • 然也然也:图片名字以及图片格式,能访问到吗?
      • 8c1c4ce66391:有的图片能获取 有的 ios Failed to load image data for asset

        [[PHImageManager defaultManager] requestImageDataForAsset:asset options:phImageRequestOptions resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {

        NSData *imageData = imageData;

        }]

        为什么啊。好疑惑
      • 8c1c4ce66391:NSURL *imageAssetUrl = [info objectForKey:UIImagePickerControllerReferenceURL];

        PHFetchResult*result = [PHAsset fetchAssetsWithALAssetURLs:@[imageAssetUrl] options:nil];

        PHAsset *asset = [result firstObject];

        PHImageRequestOptions *phImageRequestOptions = [[PHImageRequestOptions alloc] init];

        [[PHImageManager defaultManager] requestImageDataForAsset:asset options:phImageRequestOptions resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {

        NSData *imageData = imageData;

        }]
        用这个获取原图数据。。报错
        ios Failed to load image data for asset

        Remover:PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
        options.networkAccessAllowed = YES;
      • chenyingsunny:您好,requestImageDataForAsset方法获取的imageData,直接上传到服务器,图片的方向是不对的,所以说imageData没有附带图片的方向信息,请问如何解决这个问题呢?
      • 黍离离:我在- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary*)info;这个方法中打印info发现只有三个key,没有UIImagePickerControllerEditedImage,这是怎么回事啊
        OlsonXia:应该是需要设置imagePickerController.allowsEditing

      本文标题:使用UIImagePickerController选取图片并访问

      本文链接:https://www.haomeiwen.com/subject/yviydttx.html