iOS 获取系统相册图片
2016-07-09 本文已影响2770人
紧张的牛排
-
iOS获取系统相册图片方法有三种:
UIImagePickerController
,AssetsLibrary
和Photos
。
iOS 系统相册
1. UIImagePickerController
- 这种方法比较简单,但灵活性差,我们直接看实例。
1.1 初始化控制器
UIImagePickerController *pickerCtr = [[UIImagePickerController alloc] init];
pickerCtr.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
pickerCtr.delegate = self;
1.2 打开相册
[self presentViewController:pickerCtr animated:YES completion:nil];
1.3 选择某个图片时系统调用代理方法
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
NSString *type = [info objectForKey:UIImagePickerControllerMediaType];
if ([type isEqualToString:@"public.image"]) {
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
//process image
[picker dismissViewControllerAnimated:YES completion:nil];
}
}
1.4 取消选择图片时系统调用代理方法
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissViewControllerAnimated:YES completion:nil];
}
2. AssetsLibrary(已经在iOS8抛弃了)
- 这种方法比较高级,自由性强,基本满足你所有操作,当然不能满足你也无能为力了,没有其他方法了。
2.1导入头文件
#import <AssetsLibrary/AssetsLibrary.h>
2.2创建AssetsLibrary
对象并初始化
//在@interface中
@property (nonatomic, strong) ALAssetsLibrary *photoLibrary;
//在@implementation
- (ALAssetsLibrary *)photoLibrary {
if (!_photoLibrary) {
_photoLibrary = [[ALAssetsLibrary alloc] init];
}
return _photoLibrary;
}
2.3 获取相册图片信息
- ALAssetsGroupType相册类型
ALAssetsGroupLibrary NS_ENUM_DEPRECATED_IOS(4_0, 9_0) = (1 << 0), // The Library group that includes all assets.
ALAssetsGroupAlbum NS_ENUM_DEPRECATED_IOS(4_0, 9_0) = (1 << 1), // All the albums synced from iTunes or created on the device.
ALAssetsGroupEvent NS_ENUM_DEPRECATED_IOS(4_0, 9_0) = (1 << 2), // All the events synced from iTunes.
ALAssetsGroupFaces NS_ENUM_DEPRECATED_IOS(4_0, 9_0) = (1 << 3), // All the faces albums synced from iTunes.
ALAssetsGroupSavedPhotos NS_ENUM_DEPRECATED_IOS(4_0, 9_0) = (1 << 4), // The Saved Photos album.
#if __IPHONE_5_0 <= __IPHONE_OS_VERSION_MAX_ALLOWED
ALAssetsGroupPhotoStream NS_ENUM_DEPRECATED_IOS(5_0, 9_0) = (1 << 5), // The PhotoStream album.
#endif
ALAssetsGroupAll NS_ENUM_DEPRECATED_IOS(4_0, 9_0) = 0xFFFFFFFF, // The same as ORing together all the available group types,
- ALAssetsFilter相册过滤器
//Get all photos assets in the assets group.
allPhotos;
// Get all video assets in the assets group.
allVideos;
// Get all assets in the group.
allAssets;
- group中获取图片方法
/**
@param NSIndexSet 需要获取的相册中图片范围
@param NSEnumerationOptions 获取图片的顺序(顺序还是逆序)
//ALAssetsGroupEnumerationResultsBlock的参数
@param result 照片ALAsset对象
@param index 当前result在该group相册中的位置,第index位置上
@param *stop 需要停止的时候 *stop = YES就停止继续运行当前相册group
*/
enumerateAssetsAtIndexes:(NSIndexSet *)indexSet options:(NSEnumerationOptions)options usingBlock:(ALAssetsGroupEnumerationResultsBlock)enumerationBlock
- ** 该开始获取相册图片了**
- (void)getPhotoAlbumAsset {
[self.photoLibrary enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
//只读图片
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
//该相册照片数量
NSInteger photoNumber = [group numberOfAssets];
NSIndexSet *IndexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, photoNumber)];
[group enumerateAssetsAtIndexes:IndexSet options:NSEnumerationReverse usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
if([[result valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypePhoto]) {
ALAssetRepresentation *representation = [result defaultRepresentation];
NSURL *photoUrl = [representation url];
NSDate *imageDate = [result valueForProperty:ALAssetPropertyDate];
//缩略图
UIImage *image1 = [UIImage imageWithCGImage:result.thumbnail];
//屏幕分辨率图
UIImage *image2 = [representation fullScreenImage];
//原图
UIImage *image3 = [representation fullScreenImage];
}
}];
if (group == NULL) {
NSLog(@"读取所有相册结束");
}
} failureBlock:^(NSError *error) {
NSLog(@"获取相册图片失败");
}];
}
- 注意
- group为NULL时,所有相册都读完了。
- 如果多次循环访问
NSDictionary *metadata = [representation metadata]
会内存异常,原因是多次创建了metadata的字典,你的方法从当前的runloop
中返回前不会释放内存,因此内存中加载了多个metadata。
解决方法如下,没有对象持有metadata时被自动释放:
@autoreleasepool {
metadata = [representation metadata];
}
- 有些时候,先存储图片Url,需要的时候再读图片的需求,此时需要注意,这些Url只有在创建的
photoLibrary
的生命周期内有效,如果photoLibrary
销毁了获取的Url也失效。
- 用Url获取图片方法
[self.photoLibrary assetForURL:photoUrl resultBlock:^(ALAsset *asset) {
ALAssetRepresentation *representation = [result defaultRepresentation];
NSURL *photoUrl = [representation url];
//缩略图
UIImage *image1 = [UIImage imageWithCGImage:result.thumbnail];
//屏幕分辨率图
UIImage *image2 = [representation fullScreenImage];
//原图
UIImage *image3 = [representation fullScreenImage];
} failureBlock:^(NSError *error) {
}];
3. Photos
-
Photos
是iOS8
之后支持的相册访问的库,苹果重构AssetsLibrary
之后的产物。
3.1导入头文件
#import <Photos/Photos.h>
3.2 设置需要检索的相册类型配置,需要照片或视频在这里配置,或者隐藏的照片等等
PHFetchOptions *options = [PHFetchOptions new];
PHFetchResult *topLevelUserCollections = [PHAssetCollection fetchTopLevelUserCollectionsWithOptions:options];
PHAssetCollectionSubtype subType = PHAssetCollectionSubtypeAlbumRegular;
PHFetchResult *smartAlbumsResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum
subtype:subType
options:options];
3.3 遍历出需要的相册分类
NSMutableArray *photoGroups = [NSMutableArray array];
[topLevelUserCollections enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([obj isKindOfClass:[PHAssetCollection class]]) {
PHAssetCollection *asset = (PHAssetCollection *)obj;
PHFetchResult *result = [PHAsset fetchAssetsInAssetCollection:asset options:[PHFetchOptions new]];
if (result.count > 0) {
PhotoAssetGroup *g = [PhotoAssetGroup groupWithName:asset.localizedTitle fetchResult:result];
[photoGroups addObject:g];
}
}
}];
[smartAlbumsResult enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([obj isKindOfClass:[PHAssetCollection class]]) {
PHAssetCollection *asset = (PHAssetCollection *)obj;
PHFetchOptions *options = [[PHFetchOptions alloc] init];
options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]];
PHFetchResult *result = [PHAsset fetchAssetsInAssetCollection:asset options:options];
if(result.count > 0 && asset.assetCollectionSubtype != PHAssetCollectionSubtypeSmartAlbumVideos) {
PhotoAssetGroup *g = [PhotoAssetGroup groupWithName:asset.localizedTitle fetchResult:result];
[photoGroups addObject:g];
}
}
}];
3.4 根据相册分类查找所有照片信息
- (NSArray<PhotoAsset *> *)fetchPhotos:(NSArray<PhotoAssetGroup *> *)groups {
NSMutableArray *photoAssets = [NSMutableArray array];
for (PhotoAssetGroup *g in groups) {
__weak typeof(self)weakSelf = self;
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, g.result.count)];
[g.result enumerateObjectsAtIndexes:indexSet options:NSEnumerationReverse usingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
PHAsset *asset = (PHAsset*)obj;
if (asset.mediaType == PHAssetMediaTypeImage) {
if (![weakSelf.imageProcessor checkAlreadyProcessed:asset.localIdentifier]) {
PhotoAsset *pAsset = [PhotoAsset assetWthLocaleIdentifier:asset.localIdentifier creationDate:asset.creationDate];
if (![photoAssets containsObject:pAsset]) {
[photoAssets addObject:pAsset];
}
}
}
}];
}
[photoAssets sortWithOptions:NSSortStable usingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
PhotoAsset *asset1 = obj1;
PhotoAsset *asset2 = obj2;
return ([asset1.creationDate compare:asset2.creationDate] == NSOrderedAscending);
}];
return photoAssets;
}
3.5 PhotoAsset
和PhotoAssetGroup
为自定义类
@interface PhotoAsset : NSObject
@property (nonatomic, copy, readonly) NSString *localIdentifier;
@property (nonatomic, strong) NSDate *creationDate;
- (PhotoAsset *)initWithLocaleIdentifier:(NSString *)identifier creationDate:(NSDate *)date;
+ (PhotoAsset *)assetWthLocaleIdentifier:(NSString *)identifier creationDate:(NSDate *)date;
@end
@interface PhotoAssetGroup : NSObject
@property (nonatomic, copy) NSString *groupName;
@property (nonatomic, strong) PHFetchResult *result;
- (PhotoAssetGroup *)initWithName:(NSString *)name fetchResult:(PHFetchResult *)result;
+ (PhotoAssetGroup *)groupWithName:(NSString *)name fetchResult:(PHFetchResult *)result;
@end
- 如果文章对你有帮助,请点下“喜欢”吧,感谢!