說明
在iOS8以后正塌,AssetsLibrary被棄用当纱,蘋果要求用Photos呛每。查了一些資料,比較系統(tǒng)的使用Photos庫的文章不是很多坡氯,這里總結(jié)一下晨横。
一、<Photos/Photos.h>箫柳,對象說明
- PHAsset:媒體資源對象手形,可能是圖片,或者視頻悯恍;
- PHAssetCollection:相簙對象叁幢,包含一個相冊的所有信息;
- PHImageManager:圖片管理坪稽,一個單例曼玩,可以通過asset獲取圖片;
- PHImageRequestOptions:圖片請求選項窒百;
- PHFetchResult:查找的結(jié)果黍判;
- PHFetchOptions:查找請求的選項;
二篙梢、獲取系統(tǒng)相冊
__block BOOL showAlbums = YES;
WYPhotoLibraryController *library = (WYPhotoLibraryController *)self.navigationController;
//iOS8以后,使用PHAsset
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
//獲取所有系統(tǒng)相冊
PHFetchResult *smartAlbumsFetchResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:fetchOptions];
//遍歷相冊
[smartAlbumsFetchResult enumerateObjectsUsingBlock:^(PHAssetCollection *collection, NSUInteger idx, BOOL *stop) {
showAlbums = NO;
PHFetchOptions *fetchOptionsAlbums = [[PHFetchOptions alloc] init];
//通過設(shè)置選擇器顷帖,獲取需要的資源
switch (library.photoFilterType) {
case WYPhotoFilterAllImage:
fetchOptionsAlbums.predicate = [NSPredicate predicateWithFormat:@"mediaType == %d", PHAssetMediaTypeImage];
break;
case WYPhotoFilterAllVideo:
fetchOptionsAlbums.predicate = [NSPredicate predicateWithFormat:@"mediaType == %d", PHAssetMediaTypeVideo];
break;
default:
break;
}
//有可能是PHCollectionList,會造成crash渤滞,過濾掉
if ([collection isKindOfClass:[PHAssetCollection class]]) {
//從相冊中獲取數(shù)據(jù)
PHFetchResult *fetchResult = [PHAsset fetchAssetsInAssetCollection:collection options:fetchOptionsAlbums];
//去掉視頻贬墩、最近刪除、最近添加
if (![collection.localizedTitle isEqualToString:@"Recently Deleted"] &&
![collection.localizedTitle isEqualToString:@"Recently Added"] &&
![collection.localizedTitle isEqualToString:@"Videos"]) {
if (fetchResult.count > 0) {
WYPhotoGroup *group = [[WYPhotoGroup alloc] init];
group.groupName = collection.localizedTitle;
group.count = fetchResult.count;
group.assetCollection = collection;
group.fetchResult = fetchResult;
[self.photoGroups addObject:group];
}
}
}
}];
三妄呕、獲取自定義相冊
//獲取所有自定義相冊
PHFetchResult *userAlbumsFetchResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:fetchOptions];
//遍歷相冊
[userAlbumsFetchResult enumerateObjectsUsingBlock:^(PHAssetCollection *collection, NSUInteger idx, BOOL *stop) {
showAlbums = NO;
PHFetchOptions *fetchOptionsAlbums = [[PHFetchOptions alloc] init];
switch (library.photoFilterType) {
case WYPhotoFilterAllImage:
fetchOptionsAlbums.predicate = [NSPredicate predicateWithFormat:@"mediaType == %d", PHAssetMediaTypeImage];
break;
case WYPhotoFilterAllVideo:
fetchOptionsAlbums.predicate = [NSPredicate predicateWithFormat:@"mediaType == %d", PHAssetMediaTypeVideo];
break;
default:
break;
}
PHFetchResult *fetchResult = [PHAsset fetchAssetsInAssetCollection:collection options:fetchOptionsAlbums];
if (fetchResult.count > 0) {
WYPhotoGroup *group = [[WYPhotoGroup alloc] init];
group.groupName = collection.localizedTitle;
group.count = fetchResult.count;
group.assetCollection = collection;
group.fetchResult = fetchResult;
[self.photoGroups addObject:group];
}
}];
四陶舞、獲取相冊的封面(相冊中的最后一張圖片)
- (void)setGetThumbnail:(void (^)(UIImage *))getThumbnail {
_getThumbnail = getThumbnail;
//如果有相冊的封面緩存圖片,直接使用
if (_cacheThumbImage) {
_getThumbnail(_cacheThumbImage);
return;
}
//獲取封面
if ([_assetCollection isKindOfClass:[PHCollection class]]) {
//定義一個查找結(jié)果
if (!_fetchResult) {
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
_fetchResult = [PHCollection fetchCollectionsInCollectionList:_assetCollection options:fetchOptions];
}
PHFetchResult *tmpFetchResult = _fetchResult;
//獲取最后一個查找資源
PHAsset *tmpAsset = [tmpFetchResult objectAtIndex:tmpFetchResult.count - 1];
//獲取圖片绪励,并剪切
PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc] init];
requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
requestOptions.resizeMode = PHImageRequestOptionsResizeModeExact;
[[PHImageManager defaultManager] requestImageForAsset:tmpAsset targetSize:CGSizeMake(200, 200) contentMode:PHImageContentModeAspectFill options:requestOptions resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
BOOL download = ![info[PHImageCancelledKey] boolValue] && ![info[PHImageErrorKey] boolValue] && ![info[PHImageResultIsDegradedKey] boolValue];
if (download) {
float scale = result.size.height / kThumbImageHeight;
_cacheThumbImage = [UIImage imageWithCGImage:result.CGImage scale:scale orientation:UIImageOrientationUp];
_getThumbnail(_cacheThumbImage);
}
}];
}
}
五肿孵、遍歷相冊中的所有資源唠粥,并封裝對象
- (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block {
if (_assetCollection) {
if ([_assetCollection isKindOfClass:[PHCollection class]]) {
if (!_fetchResult) {
PHFetchOptions *tmpFetchOptions = [[PHFetchOptions alloc] init];
_fetchResult = [PHCollection fetchCollectionsInCollectionList:_assetCollection options:tmpFetchOptions];
}
[(PHFetchResult *) _fetchResult enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if (obj) {
WYPhoto *photo = [[WYPhoto alloc] init];
photo.asset = obj;
[weakSelf.photos addObject:photo];
}
if (weakSelf.group.count-1 ==idx) {
[weakSelf.collectionView reloadData];
}
}];
}
}
}
六、獲得一個資源(PHAsset)的文件大小
- (void)setGetFileSize:(void (^)(NSInteger))getFileSize {
_getFileSize = getFileSize;
if (_asset) {
if (_cacheFileSize > 0) {
_getFileSize(_cacheFileSize);
return;
}
//視頻資源和圖片資源獲取文件大小的方式不同
if (self.mediaType == WYPhotoMediaTypeVideo) {
PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
[[PHImageManager defaultManager] requestAVAssetForVideo:_asset options:options resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
if ([asset isKindOfClass:[AVURLAsset class]]) {
AVURLAsset *urlAsset = (AVURLAsset *)asset;
NSNumber *size;
[urlAsset.URL getResourceValue:&size forKey:NSURLFileSizeKey error:nil];
_cacheFileSize = [size floatValue]; // _cacheFileSize / (1024 * 1024) 轉(zhuǎn)MB
_getFileSize(_cacheFileSize);
}
}];
}else {
[[PHImageManager defaultManager] requestImageDataForAsset:_asset options:nil resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
_cacheFileSize = imageData.length; // _cacheFileSize / (1024 * 1024) 轉(zhuǎn)MB
_getFileSize(_cacheFileSize);
}];
}
}
}
七停做、獲得一個資源(PHAsset)的縮略圖
- (void)setGetThumbnail:(void (^)(UIImage *))getThumbnail {
_getThumbnail = getThumbnail;
if (_asset) {
if (_cacheThumbImage) {
_getThumbnail(_cacheThumbImage);
return;
}
if ([_asset isKindOfClass:[PHAsset class]]) {
PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc] init];
requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
requestOptions.resizeMode = PHImageRequestOptionsResizeModeExact;
[[PHImageManager defaultManager] requestImageForAsset:_asset targetSize:CGSizeMake(200, 200) contentMode:PHImageContentModeAspectFill options:requestOptions resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
BOOL download = ![info[PHImageCancelledKey] boolValue] && ![info[PHImageErrorKey] boolValue] && ![info[PHImageResultIsDegradedKey] boolValue];
if (download) {
_cacheThumbImage = result;
_getThumbnail(_cacheThumbImage);
}
}];
}
}
}
八晤愧、獲得一個資源(PHAsset)的高清圖
- (void)setGetFullImage:(void (^)(UIImage *))getFullImage {
_getFullImage = getFullImage;
if (_asset) {
if (_cacheFullImage) {
_getFullImage(_cacheFullImage);
return;
}
if ([_asset isKindOfClass:[PHAsset class]]) {
PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc] init];
requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
requestOptions.resizeMode = PHImageRequestOptionsResizeModeExact;
//圖的寬度
CGFloat photoWidth = [UIScreen mainScreen].bounds.size.width;
//圖寬高比
CGFloat aspectRatio = ((PHAsset*)_asset).pixelWidth / (CGFloat)((PHAsset*)_asset).pixelHeight;
//屏幕分辨率
//[[UIScreen main] scale] == 1; //代表320 x 480 的分辨率
//[[UIScreen main] scale] == 2; //代表640 x 960 的分辨率
//[[UIScreen main] scale] == 3; //代表1242 x 2208 的分辨率
CGFloat multiple = [UIScreen mainScreen].scale;
//圖寬度,像素
CGFloat pixelWidth = photoWidth * multiple;
//圖高度蛉腌,像素
CGFloat pixelHeight = pixelWidth / aspectRatio;
//允許從iCloud上下載
requestOptions.networkAccessAllowed = YES;
requestOptions.progressHandler = ^(double progress, NSError * _Nullable error, BOOL * _Nonnull stop, NSDictionary * _Nullable info) {
if (self.getNetworkProgressHandler) {
self.getNetworkProgressHandler(progress, error, stop, info);
}
};
[[PHImageManager defaultManager] requestImageForAsset:_asset targetSize:CGSizeMake(pixelWidth, pixelHeight) contentMode:PHImageContentModeAspectFill options:requestOptions resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
BOOL download = ![info[PHImageCancelledKey] boolValue] && ![info[PHImageErrorKey] boolValue] && ![info[PHImageResultIsDegradedKey] boolValue];
if (download) {
_cacheFullImage = result;
_getFullImage(_cacheFullImage);
}
}];
}
}
}