说明
在iOS8以后,AssetsLibrary被弃用,苹果要求用Photos。查了一些资料,比较系统的使用Photos库的文章不是很多,这里总结一下。
一、<Photos/Photos.h>,对象说明
- PHAsset:媒体资源对象,可能是图片,或者视频;
- PHAssetCollection:相簙对象,包含一个相册的所有信息;
- PHImageManager:图片管理,一个单例,可以通过asset获取图片;
- PHImageRequestOptions:图片请求选项;
- PHFetchResult:查找的结果;
- PHFetchOptions:查找请求的选项;
二、获取系统相册
__block BOOL showAlbums = YES;
WYPhotoLibraryController *library = (WYPhotoLibraryController *)self.navigationController;
//iOS8以后,使用PHAsset
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
//获取所有系统相册
PHFetchResult *smartAlbumsFetchResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:fetchOptions];
//遍历相册
[smartAlbumsFetchResult 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;
}
//有可能是PHCollectionList,会造成crash,过滤掉
if ([collection isKindOfClass:[PHAssetCollection class]]) {
//从相册中获取数据
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]]) {
//定义一个查找结果
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) 转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) 转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);
}
}];
}
}
}
网友评论