[iOS]坑爹的ALAsset(Assets Library Framework)

Assets Library Framework 能够用来作iOS上的多选器,选照片视频啥的啦就不介绍了。html

目前的项目有点相似dropbox,能够选择设备内的照片而后帮你上传文件,使用了Assets Library Framework,背景如此。ios

 

ALAsset能够当作是一个你选择的文件的包装类,从中能够取到一个叫作ALAssetPresentation的对象(defaultRepresentation),而后若是是图片的话里面能够获得全屏图、全尺寸图、metadata、size等等有用的信息。app

问题出现了:当用户使用iPhone/iPad内置的Photos应用修改了照片保存后,使用Assets Library Framework选择的时候看到的是修改后的缩略图OK;defaultPresentation里面的全屏图(fullScreenImage)也是修改后的OK;可是,可是!全尺寸图(fullResolutionImage)是未修改的图,Asset给出的文件url若是你直接上传,大部分看图软件打开会显示原图!(起码咱们项目对接的server端生成给咱们的缩略图是原图的缩略图,下载这个图直接用imageView看也是原图),坑爹啊!ide

回去Photos应用打开这个图片进入编辑状态能够看到有个按钮亮了,叫作”Revert to Original“,点一下图片还原了。ui

原理是Photos对图片的处理,并无真的保存一个新的图片,而是将处理经过一个叫作”AdjustmentXMP“的属性写进原图的metadata中了。url

 

这可如何是好?通过研究得出了下面的解决方案,但愿对不知道的人有所帮助:spa

1. 判断asset是图片code

2. 取到asset中的defaultRepresentation(如下简称rep)orm

3. 取到rep中metadata的”AdjustmentXMP“(如下简称adj)视频

4. 若是有adj,将adj变成一组CIFilter

5. 取到原图fullResolutionImage(如下简称img)

6. 使用CIFilter逐一”加工“img,最后生成的就是想要的图片了

7. do whatever you want... 好比咱们项目是把生成的图片存成临时文件而后上传

 

示例代码以下(asset是Assets Library Framework返回的ALAsset对象):

 1 // 处理被iOS自带Photos修改过的图片
 2     if ([[asset valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypePhoto]) {
 3         ALAssetRepresentation *rep = [asset defaultRepresentation];
 4         NSString *adj = [rep metadata][@"AdjustmentXMP"];
 5         if (adj) {
 6             CGImageRef fullResImage = [rep fullResolutionImage];
 7             NSData *xmlData = [adj dataUsingEncoding:NSUTF8StringEncoding];
 8             CIImage *image = [CIImage imageWithCGImage:fullResImage];
 9             NSError *error = nil;
10             NSArray *filters = [CIFilter filterArrayFromSerializedXMP:xmlData
11                                                      inputImageExtent:[image extent]
12                                                                 error:&error];
13             CIContext *context = [CIContext contextWithOptions:nil];
14             if (filters && !error) {
15                 for (CIFilter *filter in filters) {
16                     [filter setValue:image forKey:kCIInputImageKey];
17                     image = [filter outputImage];
18                 }
19                 fullResImage = [context createCGImage:image fromRect:[image extent]];
20                 UIImage *result = [UIImage imageWithCGImage:fullResImage
21                                                       scale:[rep scale]
22                                                 orientation:(UIImageOrientation)[rep orientation]];
23                 // do whatever you want with the result image then.
24             }
25         }
26     }

 

最后的最后,在研究此问题的同时,在小呀小苹果的官网Assets Library Framework Reference发现以下一段话:

IMPORTANT

In iOS 8.0 and later, use the Photos framework instead of the Assets Library framework. The Photos framework provides more features and better performance for working with a user’s photo library. See Photos Framework Reference

 

 

Thx for reading!

相关文章
相关标签/搜索