使用UIImagePickerController选取图片并访问原图

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 开发之照片框架详解。

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

你可能感兴趣的:(使用UIImagePickerController选取图片并访问原图)