PhotoKit的組成
PHAssetCollection:PHCollection的子類,代表一個相冊或者一個時刻,或者一個智能相冊(例如最近刪除,視頻列表,收藏等)
PHFetchResult:一系列資源的集合,也可以是相冊或者圖片的集合,PHAssetCollection的類方法返回的就是PHFetchResult
PHFetchOptions:獲取資源時的參數(shù),可以傳nil,傳nil默認(rèn)使用系統(tǒng)的
PHAsset:代表照片庫中的一個資源,跟ASset類似,通過PHAsset可以獲取可保存資源
PHImageManager:用于處理資源的加載,加載資源的過程帶有緩存處理,可以通過傳入一個 PHImageRequestOptions 控制資源的輸出尺寸等規(guī)格
PHImageRequestOptions: 如上面所說,控制加載圖片時的一系列參數(shù)
ios8-photo-kit.png
PHPhotoLibrary
+ (PHPhotoLibrary *)sharedPhotoLibrary //獲得實例
+ (PHAuthorizationStatus)authorizationStatus //獲得當(dāng)前用戶授權(quán)情況
返回一個PHAuthorizationStatus類型的枚舉:
PHAuthorizationStatusNotDetermined 用戶還未選擇
PHAuthorizationStatusRestricted 家長模式 不允許
PHAuthorizationStatusDenied 不同意訪問
PHAuthorizationStatusAuthorized 同意訪問
//在第一次獲取時,系統(tǒng)提示選擇完后的回調(diào)方法
+ (void)requestAuthorization:(void(^)(PHAuthorizationStatus status))handler;
handler:該 block 就是用戶授權(quán)選擇完后的回調(diào),可獲得用戶選擇的結(jié)果
PHAssetCollection
獲得相冊的集合資源
+ (PHFetchResult<PHAssetCollection *> *)fetchAssetCollectionsWithType:(PHAssetCollectionType)type subtype:(PHAssetCollectionSubtype)subtype options:(nullable PHFetchOptions *)options;
返回一個相冊集合資源,返回的是PHFetchResult對象集合,集合里面是PHAssetCollection類型的對象.
type:相冊類型, PHAssetCollectionType類型的枚舉,
subtype:子類型, PHAssetCollectionSubtype的枚舉,
PHFetchOptions: PHFetchOptions的一個實例,可以為空,主要是為了對獲得資源做一些配置和排序等.可以為 nil.
PHAssetCollectionType:
PHAssetCollectionTypeAlbum //相冊
PHAssetCollectionTypeSmartAlbum //智能相冊
PHAssetCollectionTypeMoment //時刻
PHAssetCollectionSubtype:
常規(guī)的子類型
PHAssetCollectionSubtypeAlbumRegular 常規(guī)的
PHAssetCollectionSubtypeAlbumSyncedEvent 使用 iTunes 同步操作過來的相冊
PHAssetCollectionSubtypeAlbumSyncedFaces 使用 iTuens同步操作過來的人物相冊
PHAssetCollectionSubtypeAlbumSyncedAlbum 使用iTunes 同步的所有相冊
PHAssetCollectionSubtypeAlbumImported 從外界導(dǎo)入的相冊
經(jīng)分享的子類型
PHAssetCollectionSubtypeAlbumMyPhotoStream 從相冊分享得到
PHAssetCollectionSubtypeAlbumCloudShared 從 cloud 分享得到
智能相冊子類型
PHAssetCollectionSubtypeSmartAlbumGeneric 通用的
PHAssetCollectionSubtypeSmartAlbumPanoramas 全景
PHAssetCollectionSubtypeSmartAlbumVideos 視屏
PHAssetCollectionSubtypeSmartAlbumFavorites 收藏
PHAssetCollectionSubtypeSmartAlbumTimelapses 延時視屏,也會在PHAssetCollectionSubtypeSmartAlbumVideos在出現(xiàn)
PHAssetCollectionSubtypeSmartAlbumAllHidden 隱藏的
PHAssetCollectionSubtypeSmartAlbumRecentlyAdded 最近添加
PHAssetCollectionSubtypeSmartAlbumBursts 連拍
PHAssetCollectionSubtypeSmartAlbumSlomoVideos Slomo是slow motion的縮寫,高速攝影慢動作解析
PHAssetCollectionSubtypeSmartAlbumUserLibrary 用戶所有的資源
PHAssetCollectionSubtypeSmartAlbumSelfPortraits 所有前置攝像頭拍的照片和視屏
PHAssetCollectionSubtypeSmartAlbumScreenshots 所有的截屏圖
不關(guān)心子類型時的全部資源
PHAssetCollectionSubtypeAny = NSIntegerMax
PHFetchResult
count 相冊中圖片的數(shù)量
//遍歷相冊資源中每個相冊組的信息
- (void)enumerateObjectsUsingBlock:(void (^)(ObjectType obj, NSUInteger idx, BOOL *stop))block;
PHFetchOptions
對使用 PHAsset, PHCollection, PHAssetCollection, 和 PHCollectionLis 的方法時出入的參數(shù),主要對獲取到資源做一些配置和排序等,一般為 nil, 默認(rèn)使用系統(tǒng)的.
sortDescriptors 排序
includeHiddenAssets 是否顯示隱藏的相冊,默認(rèn)不顯示
includeAssetSourceTypes; //獲取到相冊的類型
PHAssetSourceType類型的枚舉,默認(rèn)PHAssetSourceTypeNone
PHAssetSourceTypeNone 都沒有,就獲得到就是常規(guī)的
PHAssetSourceTypeUserLibrary 用戶所有的
PHAssetSourceTypeCloudShared 分享的
PHAssetSourceTypeiTunesSynced iTunes 同步的
PHAsset
PHAsset:每個照片的詳細(xì)信息
mediaType:資源的類型
//遍歷獲得PHAsset的集合
+ (PHFetchResult<PHAsset *> *)fetchAssetsInAssetCollection:(PHAssetCollection *)assetCollection options:(nullable PHFetchOptions *)options;
PHImageManager
PHImageManager:管理PHAsset的一個類,對資源進(jìn)行管理和篩選
+ (PHImageManager *)defaultManager; //獲得該實例.
//經(jīng)刪選和限制條件獲得具體的資源UIImage.
- (PHImageRequestID)requestImageForAsset:(PHAsset *)asset
targetSize:(CGSize)targetSize
contentMode:(PHImageContentMode)contentMode
options:(nullable PHImageRequestOptions *)options resultHandler:(void (^)(UIImage *__nullable result, NSDictionary *__nullable info))resultHandler;
返回值: PHImageRequestID,是個常量,定義為:static const PHImageRequestID PHInvalidImageRequestID = 0;
asset:想要獲得信息的PHAsset的對象,
targetSize:獲得圖片的尺寸大小,這里的大小是pixel(即像素)所以換算需要用自己自己想要的尺寸乘以[UIScreen mainScreen].scale
如果想要原圖的尺寸,直接傳入PHImageManagerMaximumSize.很大很大的尺寸,系統(tǒng)會默認(rèn)返回原圖的尺寸,要注意的是傳入PHImageManagerMaximumSize時,則 contentMode 無論傳入什么值都會被視為PHImageContentModeDefault.,另外這個尺寸只是理想的,其實返回的圖片不是這個尺寸,需要進(jìn)行處理,對圖片盡行裁剪,變成我們需要的尺寸。
contentMode:想要圖片的裁剪方式, PHImageContentMode的枚舉:
PHImageContentModeAspectFit 適合的
PHImageContentModeAspectFill 鋪滿的
PHImageContentModeDefault = PHImageContentModeAspectFit
options: PHImageRequestOptions的實例,包括控制圖片版本,質(zhì)量,裁剪參數(shù)等的一個類.
resultHandler:成功回調(diào)block,
result:獲取到的具體圖片,
info:關(guān)于圖片的一些信息,如是否來自 cloud, 是否是原圖等.
PHCachingImageManager
PHCachingImageManager是PHImageManager的子類,主要作用在獲取圖片的時候做緩存和清理的一個類
//緩存圖片
- (void)startCachingImagesForAssets:(NSArray<PHAsset *> *)assets targetSize:(CGSize)targetSize contentMode:(PHImageContentMode)contentMode options:(nullable PHImageRequestOptions *)options;
assets:要緩存獲取 PHAsset 類型對象的集合.
targetSize:想要緩存的尺寸.
contentMode:裁剪方法,
options:傳入的控制參數(shù)類.
取消緩存操作.
- (void)stopCachingImagesForAssets:(NSArray<PHAsset *> *)assets targetSize:(CGSize)targetSize contentMode:(PHImageContentMode)contentMode options:(nullable PHImageRequestOptions *)options;
assets:要緩存獲取 PHAsset 類型對象的集合.
targetSize:緩存的尺寸.
contentMode:裁剪方法,
options:傳入的控制參數(shù)類.
PHImageRequestOptions
deliveryMode //控制圖片質(zhì)量和獲取速度的 api
PHImageRequestOptionsDeliveryMode類型的枚舉,只有synchronous屬性設(shè)置為 YES,即異步獲取有限
PHImageRequestOptionsDeliveryModeOpportunistic 圖片質(zhì)量和獲取速度均衡
PHImageRequestOptionsDeliveryModeHighQualityFormat 獲取高質(zhì)量圖片,不保證獲取速度
PHImageRequestOptionsDeliveryModeFastFormat 快速獲得,不保證質(zhì)量
resizeMode //裁剪的方式
PHImageRequestOptionsResizeMode類型的枚舉:
PHImageRequestOptionsResizeModeNone 不設(shè)置 PHImageRequestOptionsResizeModeFast 返回的圖像可能和目標(biāo)大小不一樣并且質(zhì)量較低,但效率高.
PHImageRequestOptionsResizeModeExact 返回圖像必須和目標(biāo)大小相匹配,并且圖像質(zhì)量也為高質(zhì)量圖像
代碼范例:
PHFetchOptions
PHFetchOptions *option = [[PHFetchOptions alloc]init];
option.predicate = [NSPredicate predicateWithFormat:@"mediaType == %ld", PHAssetMediaTypeImage];
option.predicate = [NSPredicate predicateWithFormat:@"mediaType == %ld", PHAssetMediaTypeVideo];
option.sortDescriptors = @[[[NSSortDescriptor alloc]initWithKey:@"createDate" ascending:YES]];
PHAssetCollection(獲取相冊列表)
PHFetchResult *myPhotoStreamAlbum = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumMyPhotoStream options:nil];
PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
PHFetchResult *topLevelUserCollections = [PHCollectionList fetchTopLevelUserCollectionsWithOptions:nil];
PHFetchResult *syncedAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumSyncedAlbum options:nil];
PHFetchResult *sharedAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumCloudShared options:nil];
NSArray *allAlbums = @[myPhotoStreamAlbum,smartAlbums,topLevelUserCollections,syncedAlbums,sharedAlbums];
for(PHFetchResult *result in allAlbums)
{
for (PHAssetCollection *collection in result) {
//過濾掉非PHAssetCollection
if (![collection isKindOfClass:[PHAssetCollection class]]) {
continue;
}
PHFetchResult *assetResult = [PHAsset fetchAssetsInAssetCollection:collection options:option];
//如果相冊里面沒有資源過濾掉
if (assetResult.count <= 0) {
continue;
}
//過濾掉最近刪除的
if ([collection.localizedTitle containsString:@"Deleted"] || [collection.localizedTitle isEqualToString:@"最近刪除"])
{
continue;
}
[_albumArray addObject:collection];
}
}
}
PHImageManager
PHImageRequestOptions *option = [[PHImageRequestOptions alloc]init];
option.resizeMode = PHImageRequestOptionsResizeModeFast;
[[PHImageManager defaultManager]requestImageForAsset:asset targetSize:fsize contentMode:PHImageContentModeAspectFill options:option resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
//這一塊為什么要加BOOL值來判斷呢,是因為有時候圖片會從iCloud下載,這個時候這個block會回調(diào)多次,此時在block里面做的操作也會被執(zhí)行多次,于是需要進(jìn)行判斷,當(dāng)圖片被取消或者錯誤或者低清圖的時候不執(zhí)行回調(diào)
BOOL downloadFinined = ![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey] && ![[info objectForKey:PHImageResultIsDegradedKey] boolValue];
if (downloadFinined && result) {
if (noCut) {
completion ? completion(result) : nil;
}else
{
//這一塊拿到的圖片其實是原先的圖片等比列縮小的,因為原先的圖片寬和高不一定相等,所以圖片會變形,需要進(jìn)行處理
result = [self customImage:result];
completion ? completion(result) : nil;
}
}
}];
//將不合適的圖片裁剪成合適的縮略圖
-(UIImage*)customImage:(UIImage*)image
{
CGSize size;
if (image.size.width*1.0/image.size.height < 1) { //高比寬大,已寬為基準(zhǔn)
size.width = image.size.width;
size.height = image.size.width;
//下面這段代碼的意思是:因為高大于寬,所以y從中間裁剪
CGImageRef imageref = CGImageCreateWithImageInRect(image.CGImage, CGRectMake(0, fabs((image.size.height - image.size.width)/2.0), size.width, size.height));
return [UIImage imageWithCGImage:imageref];
}else //寬比高大
{
size.width = image.size.height;
size.height = image.size.height;
//下面這段代碼的意思是:因為高大于寬,所以y從中間裁剪
CGImageRef imageref = CGImageCreateWithImageInRect(image.CGImage, CGRectMake( fabs((image.size.width - image.size.height)/2.0),0, size.width, size.height));
return [UIImage imageWithCGImage:imageref];
}
}