在开发,我们经常会碰到这么种需求,从相册中选择图片,一般使用UIImagePickerController这个类,但是这个类有个缺陷,不能同时选择多张图片,其实我们还有更好的方式访问相册中的图片,使用ALAssetsLibrary就是一个很好的解决方案,使用ALAssetsLibrary同时还可以将图片,和视频保存到系统照片中。
1将图片视频保存到相册中
一般步骤先初始化ALAssetsLibrary一个对象,然后通过ALAssetsLibrary的方法写到相册中去,但是有个缺陷这都写到了系统相册中,很多应用可以自己生成自己的相册,比如QQ和一些拍照app。于是写了个ALAssetsLibrary分类,可以将图片或者视频写入到制定的相册中,代码如下:
@interface ALAssetsLibrary (addALAsset)
- (void)toolWriteImageToSavedPhotosAlbum:(CGImageRef)imageRef orientation:(ALAssetOrientation)orientation completionBlock:(ALAssetsLibraryWriteImageCompletionBlock)completionBlock groupName:(NSString*)groupName;
- (void)toolWriteImageToSavedPhotosAlbum:(CGImageRef)imageRef metadata:(NSDictionary *)metadata completionBlock:(ALAssetsLibraryWriteImageCompletionBlock)completionBlock groupName:(NSString*)groupName;
- (void)toolWriteImageDataToSavedPhotosAlbum:(NSData *)imageData metadata:(NSDictionary *)metadata completionBlock:(ALAssetsLibraryWriteImageCompletionBlock)completionBlock groupName:(NSString*)groupName;
- (void)toolWriteVideoAtPathToSavedPhotosAlbum:(NSURL *)videoPathURL completionBlock:(ALAssetsLibraryWriteVideoCompletionBlock)completionBlock groupName:(NSString*)groupName;
@end
说明一下groupName就是相册的名字,根据需求命名,如果没有以groupName命名的相册,将会创建groupName命名的相册。
实现如下,只是列举一个例子:
- (void)toolWriteImageToSavedPhotosAlbum:(CGImageRef)imageRef orientation:(ALAssetOrientation)orientation completionBlock:(ALAssetsLibraryWriteImageCompletionBlock)completionBlock groupName:(NSString*)groupName
{
ALAssetsLibraryWriteImageCompletionBlock block = [self compositionBlock:completionBlock withGroupName:groupName];
[self writeImageToSavedPhotosAlbum:imageRef orientation:orientation completionBlock:block];
}
其实实现还是调用ALAssetsLibrary自身的方法,我只是对传进来的block进行了扩展,添加了创建相册和向相册中添加图片或视频的功能。对block做了什么扩展?
-(void (^)(NSURL *assetURL, NSError *error))compositionBlock:(void (^)(NSURL *assetURL, NSError *error))block withGroupName:(NSString*)groupName
{
void (^completionBlok)(NSURL *assetURL, NSError *error) = ^(NSURL *assetURL, NSError *error)
{
[self addAssetsGroupAlbumWithName:groupName resultBlock:^(ALAssetsGroup *group) {
//图片中没有该相册,创建成功
if (group) {
[self assetForURL:assetURL resultBlock:^(ALAsset *asset) {
[group addAsset:asset];
} failureBlock:^(NSError *error) {
//没有授权或者其他失败
}];
}//由同名的创建失败
else
{
[self enumerateGroupsWithTypes:ALAssetsGroupAlbum usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
if([[group valueForProperty:ALAssetsGroupPropertyName] isEqualToString:groupName])
{
[self assetForURL:assetURL resultBlock:^(ALAsset *asset) {
[group addAsset:asset];
} failureBlock:^(NSError *error) {
}];
*stop = YES;
}
} failureBlock:^(NSError *error) {
//没有授权或者其他失败
}];
}
} failureBlock:^(NSError *error) {
//没有授权或者其他失败
}];
block(assetURL,error);
};
return [completionBlok copy];
}
说明一下,该block是在成功保存图片视频到相册中的回调,首先尝试创建groupName命名的相册,如果已经存在groupName命名的相册,将会创建失败,放回ALAssetsGroup(可以理解为代表相册)的对象为nil。此时说明已经存在该相册,通过名称枚举该相册,得到ALAssetsGroup对象,就是我们要的相册,然后添加图片视频到该相册中。如果创建成功,直接将视频图片添加的相册中,具体见代码。通过以上方法就可以将图片,视频添加到以groupName命名的相册中 了。
2多图片选择
该功能主要是提供一种向相册获取一张或者多张的图片(当然也可以是视频,只是这里没有处理视频类型,即便选择了视频也只是获取视频的一个缩图)。说白了就是就是对ALAssetsLibrary和ALAssetsGrouph以及ALAsset的使用,当然也会用到ALAssetRepresentation,这里也用到了ALAssetRepresentation类,通过这个类可以获得ALAsset更详细的东西。
图片选择提供了三种类型,可以根据需求选择,
typedef NS_ENUM(NSInteger,ChoosetImgType)
{
//缩略图,默认为缩略图
ChoosetImgTypeThumbnail=0,
//图片的高清图
ChoosetImgTypefullResolutionImage=1,
//图片的全屏图
ChoosetImgTypefullScreenImage=2,
};
枚举相册,说明一下该方法为异步的
[self.library enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
if (group) {
JGImgGroup *imgGroup = [JGImgGroup imgGroupWithGroup:group];
[self.groupArr addObject:imgGroup];
[self.tableView reloadData];
}
} failureBlock:^(NSError *error) {
}];
从相册中枚举图片视频资源,说明一下该方法为同步的,很可能需要在子线程中获取
-(void)setupAlAssetData
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (self.imgGroup) {
[self.imgGroup.group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
if (result) {
[self.alassetArr addObject:result];
}
}];
}
dispatch_async(dispatch_get_main_queue(), ^{
[self setupUI];
});
});
}
选择图片进行回调,根据选择的图片类型
-(void)selectImg:(UIButton*)btn
{
NSMutableArray *chooseImgs = [NSMutableArray array];
if (self.chooseImgType == ChoosetImgTypeThumbnail) {
for(int i = 0 ;i < self.alassetArr.count ; i++)
{
JGDisplayImgView *displayView = self.imgViewArr[i];
if (displayView.isSelected) {
ALAsset *alasset = self.alassetArr[i];
UIImage *img = [UIImage imageWithCGImage:alasset.thumbnail];
[chooseImgs addObject:img];
}
}
}
else
{
for(int i = 0 ;i < self.alassetArr.count ; i++)
{
JGDisplayImgView *displayView = self.imgViewArr[i];
if (displayView.isSelected)
{
ALAsset *alasset = self.alassetArr[i];
ALAssetRepresentation *alassetPresentation = [alasset defaultRepresentation];
UIImage *img = nil;
if (self.chooseImgType == ChoosetImgTypefullResolutionImage) {
img = [UIImage imageWithCGImage:[alassetPresentation fullResolutionImage]];
}
else if(self.chooseImgType == ChoosetImgTypefullScreenImage)
{
img = [UIImage imageWithCGImage:[alassetPresentation fullScreenImage]];
}
if (img) {
[chooseImgs addObject:img];
}
}
}
}
if (self.delegate && [self.delegate respondsToSelector:@selector(selectSecceedWithImgs:)]) {
[self.delegate selectSecceedWithImgs:chooseImgs];
}
if (self.mainVc) {
[self.mainVc dismissViewControllerAnimated:YES completion:nil];
}
}
点击图片选择按钮,当选中时还有缩放效果,具体细节这就不说了,感兴趣可以自己下载看看,有问题可以回复,github下载地址:https://github.com/jiangtaidi/JGALAssetsLibrary