iOS 实现图库多张图片的选择原理

相信大家对单张图片的选择都比较熟悉,简单的UIImagePickerController就实现了

但是,这里多张图片实现就相对比较麻烦,先简单的展示一下我们最终要实现的效果






AssetsLibrary和PhotoKit框架都可以用来封装相册的单选与多选功能,不过ALAssetLibrary的方法在iOS 9中不被推荐了,现在都是用新的框架PhotoKit

的来实现。发现好多之前的应用自定义的XXImagePickerController都无法获取到所有的照片了,为了能让老程序也可以实现这时候就要使用AssetsLibrary+Photos来解决问题了。

正因为苹果已经做了大量的封装工作,使得开发者在使用PhotoKit的时候非常方便。

先简单介绍下ALAssetsLibrary:

ALAssetsLibrary 提供了访问iOS设备下照片应用下所有照片和视频的接口.从 ALAssetsLibrary 中可读取所有的相册数据,即 ALAssetsGroup 对象列 表;  从每个 ALAssetsGroup 中可获取到其中包含的照片或视频列表,即 ALAsset 对象列表. 其层次关系为  

ALAssetsLibrary -> ALAssetsGroup -> ALAsset -> ALAssetRepresentation. 
1) ALAssetsLibrary类:
ALAssetsLibrary类可以实现查看相册列表,增加相册,保存图片到相册等功能。
例如enumerateGroupsWithTypes方法列举所有相册。

(2) ALAssetsGroup
*ALAssetsGroup就是相册的类,可以通过valueForProperty方法查看不同属性的值,如:ALAssetsGroupPropertyName,相册名。
*ALAssetsGroup类有几个方法,posterImage方法就是相册的封面图片,numberOfAssets方法获取该相册的图片视频数量,可以通过enumerateAssetsUsingBlock方法列举出所有照片。
*ALAssetsGroup 可以使用setAssetsFilter:(ALAssetsFilter *)filter过滤照片或者视频等。
首先是获取所有相册,通过ALAssetsLibrary的实例方法得到ALAssetsGroup类数组。
复制代码
   ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init];
    NSMutableArray *groupArray = [NSMutableArray array];
    [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
        if (group) {
            [groupArray addObject:group];
            
            //通过这个可以知道相册的名字,从而也可以知道安装的部分应用
            NSLog(@"%@",group);
        }
    } failureBlock:^(NSError *error) {
        NSLog(@"Group not found!\n");
    }];
复制代码
(3) ALAsset
*ALAsset类也可以通过valueForProperty方法查看不同属性的值,如:ALAssetPropertyType,asset的类型,有三种ALAssetTypePhoto, ALAssetTypeVideo or ALAssetTypeUnknown。
*另外还可以通过该方法获取ALAssetPropertyLocation(照片位置),ALAssetPropertyDuration(视频时间),ALAssetPropertyDate(照片拍摄日期)等。
可以通过thumbnail方法就是获取该照片。
*根据相册获取该相册下所有图片,通过ALAssetsGroup的实例方法得到ALAsset类数组。
复制代码
 [_group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
        if (result) {
            [imageArray addObject:result];
            NSLog(@"%@",result);
             iv.image=[UIImage imageWithCGImage: result.thumbnail];
NSString *type=[result valueForProperty:ALAssetPropertyType];
        }
    }];
复制代码
 
 
(4) ALAssetsFilter:提供过滤照片或者视频的实例等。

(5) ALAssetRepresentation
ALAsset类有一个defaultRepresentation方法,返回值是ALAssetRepresentation类,该类的作用就是获取该资源图片的详细资源信息。
复制代码
//
//获取资源图片的详细资源信息
ALAssetRepresentation* representation = [asset defaultRepresentation];
//获取资源图片的长宽
CGSize dimension = [representation dimensions];
 //获取资源图片的高清图
[representation fullResolutionImage];
//获取资源图片的全屏图
[representation fullScreenImage];
//获取资源图片的名字
NSString* filename = [representation filename];
NSLog(@"filename:%@",filename);
//缩放倍数
[representation scale];
//图片资源容量大小
[representation size];
//图片资源原数据
 [representation metadata];
//旋转方向
[representation orientation];
 //资源图片url地址,该地址和ALAsset通过ALAssetPropertyAssetURL获取的url地址是一样的
NSURL* url = [representation url];
NSLog(@"url:%@",url);
//资源图片uti,唯一标示符
NSLog(@"uti:%@",[representation UTI]);


       1、 每个 ALAsset 可能有多个representations表示, 即ALAssetRepresentation 对象;
       
       2、使用其defaultRepresentation 方法可获得其默认representations;

       3、使用[asset valueForProperty: ALAssetPropertyRepresentations ]可获取其所有representations的 UTI 数组;

       4、从ALAsset对象可获取缩略图 thumbnail 或 aspectRatioThumbnail ; 

再简单介绍一下photoKit的框架。photoKit的基本构成有:

     1、PHAsset: 代表照片库中的一个资源,跟 ALAsset 类似,通过 PHAsset 可以获取和保存资源

     2、PHFetchOptions: 获取资源时的参数,可以传 nil,即使用系统默认值

     3、PHAssetCollection: PHCollection 的子类,表示一个相册或者一个时刻,或者是一个「智能相册(系统提供的特定的一系列相册,例如:最近删

除,视频列表,收藏等等,如下图所示)

     4、PHFetchResult: 表示一系列的资源结果集合,也可以是相册的集合,从 PHCollection 的类方法中获得

     5、PHImageManager: 用于处理资源的加载,加载图片的过程带有缓存处理,可以通过传入一个 PHImageRequestOptions 控制资源的输出尺寸等规格

PHImageRequestOptions: 如上面所说,控制加载图片时的一系列参数

    6、PHCollectionList,表示一组 PHCollection,它本身也是一个 PHCollection,因此 PHCollection 作为一个集合,可以包含其他集合,这使到

 PhotoKit 的组成比 ALAssetLibrary 要复杂一些。另外与 ALAssetLibrary 相似,一个 PHAsset 可以同时属于多个不同的 PHAssetCollection,最常见的

photoKit获取所有照片

- (NSMutableArray *)getAllPhoto{
    NSMutableArray *arr = [NSMutableArray array];
        // 所有智能相册
    PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
    for (NSInteger i = 0; i < smartAlbums.count; i++) {
        PHCollection *collection = smartAlbums[i];
        //遍历获取相册
        if ([collection isKindOfClass:[PHAssetCollection class]]) {
            PHAssetCollection *assetCollection = (PHAssetCollection *)collection;
            PHFetchResult *fetchResult = [PHAsset fetchAssetsInAssetCollection:assetCollection options:nil];
            PHAsset *asset = nil;
            if (fetchResult.count != 0) {
                for (NSInteger j = 0; j < fetchResult.count; j++) {
                    //从相册中取出照片
                    asset = fetchResult[j];
                    PHImageRequestOptions *opt = [[PHImageRequestOptions alloc]init];
                    opt.synchronous = YES;
                    PHImageManager *imageManager = [[PHImageManager alloc] init];
                    [imageManager requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeAspectFill options:opt resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
                        if (result) {
                            [arr addObject:result];
                        }
                    }];
        }
            }
    }
        }
    
    //返回所有照片
    return arr;
}

由于此方法为同步方法 所以需要放在子线程中去执行 例如:

dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSMutableArray *arr = [self getAllPhoto];
        NSLog(@"完成%@ \n照片总数%ld", arr, arr.count);
    });​

我是用AssetsLibrary实现的,这里就简单介绍一下实现的步骤,首先添加照片,肯定是用CollectionView来实现的,声明一个数组存放选中的照片,当个照片数量为0是,返回一个cell,添加的点击时间访问图库,否则,返回cell的个数为照片数量加1,设置cell的样式,当cell的index小于等于照片数量,点击可以放大图片,点击红色按钮可以删除照片,否则的话添加照片,并且改变collectionView的frame






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值