最近做了一個自定義相冊,用到了PHotoKit的相關API,做一下備忘
基於PhotoKit,iOS8及以後支持
PhotoKit組成介紹
PhotoKit通過兩個類來管理資源
- PHImageManager: 用於處理資源的加載,加載圖片的過程帶有緩存處理,可以通過傳入一個 PHImageRequestOptions 控制資源的輸出尺寸等規格request相關api默認異步,如需同步,需設置synchronous
- PHPhotoLibrary:用於處理權限管理,資源的保存,調用performChanges方法,在changeblock中根據資源構建個 PHAssetChangeRequest 來存入
獲取相冊以及asset
PHAsset: 代表照片庫中的一個資源,跟 ALAsset 類似,通過 PHAsset 可以獲取和保存資源。
PHFetchOptions: 獲取資源時的參數,可以進行過濾和排序。可以傳 nil,即使用系統默認值。
PHFetchResult: 表示一系列的資源集合,也可以是相冊的集合。
PHAssetCollection: 表示一個相冊或者一個時刻,或者是一個「智能相冊(系統提供的特定的一系列相冊,例如:最近刪除,視頻列表,收藏等等)
PHImageRequestOptions: 如上面所說,控制加載圖片時的一系列參數
enum PHAssetCollectionType : Int {
case Album //從 iTunes 同步來的相冊,以及用戶在 Photos 中自己建立的相冊
case SmartAlbum //經由相機得來的相冊
case Moment //Photos 爲我們自動生成的時間分組的相冊
}
enum PHAssetCollectionSubtype : Int {
case AlbumRegular //用戶在 Photos 中創建的相冊,也就是我所謂的邏輯相冊
case AlbumSyncedEvent //使用 iTunes 從 Photos 照片庫或者 iPhoto 照片庫同步過來的事件。然而,在iTunes 12 以及iOS 9.0 beta4上,選用該類型沒法獲取同步的事件相冊,而必須使用AlbumSyncedAlbum。
case AlbumSyncedFaces //使用 iTunes 從 Photos 照片庫或者 iPhoto 照片庫同步的人物相冊。
case AlbumSyncedAlbum //做了 AlbumSyncedEvent 應該做的事
case AlbumImported //從相機或是外部存儲導入的相冊,完全沒有這方面的使用經驗,沒法驗證。
case AlbumMyPhotoStream //用戶的 iCloud 照片流
case AlbumCloudShared //用戶使用 iCloud 共享的相冊
case SmartAlbumGeneric //文檔解釋爲非特殊類型的相冊,主要包括從 iPhoto 同步過來的相冊。由於本人的 iPhoto 已被 Photos 替代,無法驗證。不過,在我的 iPad mini 上是無法獲取的,而下面類型的相冊,儘管沒有包含照片或視頻,但能夠獲取到。
case SmartAlbumPanoramas //相機拍攝的全景照片
case SmartAlbumVideos //相機拍攝的視頻
case SmartAlbumFavorites //收藏文件夾
case SmartAlbumTimelapses //延時視頻文件夾,同時也會出現在視頻文件夾中
case SmartAlbumAllHidden //包含隱藏照片或視頻的文件夾
case SmartAlbumRecentlyAdded //相機近期拍攝的照片或視頻
case SmartAlbumBursts //連拍模式拍攝的照片,在 iPad mini 上按住快門不放就可以了,但是照片依然沒有存放在這個文件夾下,而是在相機相冊裏。
case SmartAlbumSlomoVideos //Slomo 是 slow motion 的縮寫,高速攝影慢動作解析,在該模式下,iOS 設備以120幀拍攝。不過我的 iPad mini 不支持,沒法驗證。
case SmartAlbumUserLibrary //這個命名最神奇了,就是相機相冊,所有相機拍攝的照片或視頻都會出現在該相冊中,而且使用其他應用保存的照片也會出現在這裏。
case Any //包含所有類型
}
根據asset獲取圖片或視頻
- requestImageForAsset: targetSize:適用於有size的圖片請求。例如:列表加載,預覽
- requestImageDataForAsset:適用於沒有size的圖片請求。例如:原圖
- 視頻。。。
保存圖片或視頻
PHPhotoLibrary:用於處理資源的存入,權限管理,調用performChanges方法,在changeblock中根據資源構建個 PHAssetChangeRequest 來存入
-
authorizationStatus
-
requestAuthorization
-
向相冊中存圖片
-
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ PHAssetChangeRequest *request = [PHAssetChangeRequest creationRequestForAssetFromImage:image]; localIdentifier = request.placeholderForCreatedAsset.localIdentifier; if (location) { request.location = location; } request.creationDate = [NSDate date]; } completionHandler:^(BOOL success, NSError *error) { }];
PHImageRequestOptions:
幾個屬性控制了API的調用效果
- version:表示當前請求資源的版本:current:是否編輯,獲取當前版本;unadjusted:不帶調節的原始版本;original:原始版本,組合格式下的高保真格式
- deliveryMode:投遞方式:Opportunistic:在異步情況下會返回多個結果,同步情況下返回一個;HighQualityFormat:一個結果,高質量格式;FastFormat:一個結果,降級
- resizeMode:調整大小模式:none:不調整;fast:使用 targetSize 作爲最佳解碼的提示,當源圖像是壓縮格式(即子採樣)時,交付的圖像可能大於 targetSize;exact:與上述相同,但也保證交付的圖像與目標大小完全相同(必須在指定規範化裁剪時進行設置);
-
networkAccessAllowed:如有必要,將從iCloud下載圖像(客戶端可以使用進度處理程序監視或取消)。默認爲 NO。如果爲YES,並且請求的圖像未存儲在本地設備上,則"PhotoKit"會從 iCloud 下載圖像。若要收到有關下載進度的通知,請使用 progressHandler 屬性提供"PhotoKit"在下載圖像時定期調用的代碼塊。如果 NO(默認值),並且圖像不在本地設備上,則結果處理程序的 info 字典中的 PHImageResultIsInCloudKey 值指示除非啓用網絡訪問,否則圖像不可用。
-
synchronous:默認爲no,同步請求資源,一般僅用於後臺線程執行同步請求。如果爲NO, requestImageForAsset:targetSize:contentMode:options:resultHandler: 方法會馬上返回,PhotoKit會根據deliverymode屬性來調用結果block。如果爲YES,
requestImageForAsset:targetSize:contentMode:options:resultHandler:
方法會阻塞調用線程,直到圖片數據請求完成或錯誤發生 -
progressHandler:默認爲nil,如果您請求的圖像的數據不在本地設備上,並且您已啓用使用 networkAccessAllowed 屬性進行下載,則"PhotoKit"會定期調用您的塊以報告進度並允許您取消下載。
-
normalizedCropRect:用於獲取裁剪圖片。要請求裁剪圖像,請在相對於圖像的單位座標空間中指定裁剪矩形。在此座標系中,點 {0.0,0.0} 表示圖像的左上角,點 {1.0,1.0} 表示相對的角,此屬性默認爲 CGRectZero,不進行裁剪。如果指定裁剪矩形,則還必須爲 resizeMode 屬性指定 PHImageRequestOptionsResizeModeExact 選項。
總結:
- 在列表加載圖片或進行大圖預覽時,使用
requestImageForAsset:targetSize:contentMode:options:resultHandler:
,親測即便是請求不在本地iCloud圖片也非常快,預覽圖 - 當用戶選中圖片,設置networkAccessAllowed爲YES,加載iCloud圖片,可以根據progressHandler獲取進度
- 當需要使用高質量圖片時,根據實際情況設置deliveryMode