[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!

相關文章
相關標籤/搜索