标签:
保存(获取)图片到(自定义)相册
最近在学 iOS相关技术(绘图篇实现画板功能)的时候设计到了两个常用的知识点,那就是保存图片到相册和葱相册中获取图片。
只是个人比较好奇拓展一些技术,说的难听点叫做装牛角尖,好听点就是为了装逼而已,所以在保存相册的时候使用真及测试发现不能保存到我iPhone里 main的自定义相册里面,就查看文档和资料,也借鉴别人的分享实现了想要的功能,就把他给记录下来,这个虽然没有直接保存和获取常用但是也是一项很好的实用技术。
一:首先来看看怎么获取相册的图片:
1 // 弹出系统的相册 2 // 选择控制器(系统相册) 3 UIImagePickerController *picekerVc = [[UIImagePickerController alloc] init]; 4 5 // 设置选择控制器的来源 6 // UIImagePickerControllerSourceTypePhotoLibrary 相册集 7 // UIImagePickerControllerSourceTypeSavedPhotosAlbum:照片库 8 picekerVc.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum; 9 10 // 设置代理 11 picekerVc.delegate = self; 12 13 // modal 14 [self presentViewController:picekerVc animated:YES completion:nil];
实现代理方法:
1 #pragma mark - UIImagePickerControllerDelegate 2 // 当用户选择一张图片的时候调用 3 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 4 { 5 // 获取选中的照片 6 UIImage *image = info[UIImagePickerControllerOriginalImage]; 7 8 // 把选中的照片画到画板上 9 10 _drawView.image = image; 11 12 // dismiss 13 [self dismissViewControllerAnimated:YES completion:nil]; 14 }
注意:这里需要遵守两个协议:
<UINavigationControllerDelegate,UIImagePickerControllerDelegate>
关于只有UIImagePickerController却要遵守两个协议笔者也还在寻找答案,不过根据名字这个肯定是跟导航控制器有关,但是这设计到了底层的东西,这里就不多做解释了。
二:然后就是证明保存图片到系统的相册:
1 // 截屏 2 // 开启上下文 3 UIGraphicsBeginImageContextWithOptions(_drawView.bounds.size, NO, 0); 4 5 // 获取上下文 6 CGContextRef ctx = UIGraphicsGetCurrentContext(); 7 8 // 渲染图层 9 [_drawView.layer renderInContext:ctx]; 10 11 // 获取上下文中的图片 12 UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 13 14 // 关闭上下文 15 UIGraphicsEndImageContext(); 16 17 18 // 保存画板的内容放入相册 19 // image:写入的图片 20 // completionTarget图片保存监听者 21 // 注意:以后写入相册方法中,想要监听图片有没有保存完成,保存完成的方法不能随意乱写 22 UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
这里涉及到了图层的知识Quartz2d绘图,关于图层情查看笔者之前写的文章。
这里同样需要监听一下保存是否成功:
1 // 监听保存完成,必须实现这个方法 2 - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo 3 { 4 NSLog(@"保存图片成功"); 5 }
三:最后就是保存图片到我们在iphone中自定义相册:
保存照片还可以用ALAssetsLibrary
,ALAssetsLibrary
提供了我们对iOS设备中的相片、视频的访问,是连接应用程序和相册之间访问的一个桥梁。
接下来,我们来详细讲解一下关于系统相册权限获取、保存照片、创建自己的相簿等等功能。
这也是一种比较创建的作法,创建自己的相簿,然后把照片或者视频保存到自己的相簿中。相关代码如下:
1 ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; 2 [library addAssetsGroupAlbumWithName:@"test" resultBlock:^(ALAssetsGroup *group) { 3 4 //创建相簿成功 5 6 } failureBlock:^(NSError *error) { 7 //失败 8 }];
这个方法也是将照片保存到系统相簿里面,不是保存到自己创建的相簿里面。代码如下:
1 ALAssetsLibrary *library = [[ALAssetsLibrary alloc]init]; 2 [library writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)image.imageOrientation completionBlock:^(NSURL *asSetUrl,NSError *error){ 3 if (error) { 4 //失败 5 }else{ 6 UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"存储成功" 7 message:nil 8 delegate:nil 9 cancelButtonTitle:@"确定" 10 otherButtonTitles:nil, nil]; 11 [alert show]; 12 13 } 14 }];
获取权限
在保存照片之前,如果用户关闭相册权限,这个时候是保存失败的。如果你不做任何处理,用户是不会知道自己保存失败了。所以,我们可以在保存照片之前,做出相应的提示。如何获取这个权限呢?一般有两种方法:
创建相簿失败
保存照片失败
在上面两个方法创建自己的相簿和保存照片的失败结果里,我们可以弹出获取照片权限失败的提示。我们拿第一个创建相簿失败来举例:
1 ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; 2 [library addAssetsGroupAlbumWithName:@"test" resultBlock:^(ALAssetsGroup *group) { 3 4 //创建相簿成功 5 6 } failureBlock:^(NSError *error) { 7 UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"存储失败" 8 message:@"请打开 设置-隐私-照片 来进行设置" 9 delegate:nil 10 cancelButtonTitle:@"确定" 11 otherButtonTitles:nil, nil]; 12 [alert show]; 13 }];
在保存照片失败的结果里,我们也可以弹出相应的提示,让用户打开应用程序的相册权限。
下面这段代码是在大谷歌里面找到的,亲自测试过是可以用的,整理如下:
1 #pragma mark - 创建相册 2 - (void)createAlbum 3 { 4 ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init]; 5 NSMutableArray *groups=[[NSMutableArray alloc]init]; 6 ALAssetsLibraryGroupsEnumerationResultsBlock listGroupBlock = ^(ALAssetsGroup *group, BOOL *stop) 7 { 8 if (group) 9 { 10 [groups addObject:group]; 11 } 12 13 else 14 { 15 BOOL haveHDRGroup = NO; 16 17 for (ALAssetsGroup *gp in groups) 18 { 19 NSString *name =[gp valueForProperty:ALAssetsGroupPropertyName]; 20 21 if ([name isEqualToString:@"iOSDevTip"]) 22 { 23 haveHDRGroup = YES; 24 } 25 } 26 27 if (!haveHDRGroup) 28 { 29 //do add a group named "XXXX" 30 [assetsLibrary addAssetsGroupAlbumWithName:@"iOSDevTip" 31 resultBlock:^(ALAssetsGroup *group) 32 { 33 [groups addObject:group]; 34 35 } 36 failureBlock:nil]; 37 haveHDRGroup = YES; 38 } 39 } 40 41 }; 42 //创建相簿 43 [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAlbum usingBlock:listGroupBlock failureBlock:nil]; 44 45 [self saveToAlbumWithMetadata:nil imageData:UIImagePNGRepresentation(self.image) customAlbumName:@"iOSDevTip" completionBlock:^ 46 { 47 //这里可以创建添加成功的方法 48 49 } 50 failureBlock:^(NSError *error) 51 { 52 //处理添加失败的方法显示alert让它回到主线程执行,不然那个框框死活不肯弹出来 53 dispatch_async(dispatch_get_main_queue(), ^{ 54 55 //添加失败一般是由用户不允许应用访问相册造成的,这边可以取出这种情况加以判断一下 56 if([error.localizedDescription rangeOfString:@"User denied access"].location != NSNotFound ||[error.localizedDescription rangeOfString:@"用户拒绝访问"].location!=NSNotFound){ 57 UIAlertView *alert=[[UIAlertView alloc]initWithTitle:error.localizedDescription message:error.localizedFailureReason delegate:nil cancelButtonTitle:NSLocalizedString(@"ok", nil) otherButtonTitles: nil]; 58 59 [alert show]; 60 } 61 }); 62 }]; 63 } 64 65 - (void)saveToAlbumWithMetadata:(NSDictionary *)metadata 66 imageData:(NSData *)imageData 67 customAlbumName:(NSString *)customAlbumName 68 completionBlock:(void (^)(void))completionBlock 69 failureBlock:(void (^)(NSError *error))failureBlock 70 { 71 72 ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init]; 73 __weak ALAssetsLibrary *weakSelf = assetsLibrary; 74 void (^AddAsset)(ALAssetsLibrary *, NSURL *) = ^(ALAssetsLibrary *assetsLibrary, NSURL *assetURL) { 75 [assetsLibrary assetForURL:assetURL resultBlock:^(ALAsset *asset) { 76 [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) { 77 78 if ([[group valueForProperty:ALAssetsGroupPropertyName] isEqualToString:customAlbumName]) { 79 [group addAsset:asset]; 80 if (completionBlock) { 81 completionBlock(); 82 } 83 } 84 } failureBlock:^(NSError *error) { 85 if (failureBlock) { 86 failureBlock(error); 87 } 88 }]; 89 } failureBlock:^(NSError *error) { 90 if (failureBlock) { 91 failureBlock(error); 92 } 93 }]; 94 }; 95 [assetsLibrary writeImageDataToSavedPhotosAlbum:imageData metadata:metadata completionBlock:^(NSURL *assetURL, NSError *error) { 96 if (customAlbumName) { 97 [assetsLibrary addAssetsGroupAlbumWithName:customAlbumName resultBlock:^(ALAssetsGroup *group) { 98 if (group) { 99 [weakSelf assetForURL:assetURL resultBlock:^(ALAsset *asset) { 100 [group addAsset:asset]; 101 if (completionBlock) { 102 completionBlock(); 103 } 104 } failureBlock:^(NSError *error) { 105 if (failureBlock) { 106 failureBlock(error); 107 } 108 }]; 109 } else { 110 AddAsset(weakSelf, assetURL); 111 } 112 } failureBlock:^(NSError *error) { 113 AddAsset(weakSelf, assetURL); 114 }]; 115 } else { 116 if (completionBlock) { 117 completionBlock(); 118 } 119 } 120 }]; 121 }
ALAssetsLibrary+CustomPhotoAlbum保存照片
github
上有一个项目ALAssetsLibrary+CustomPhotoAlbum :( https://github.com/Kjuly/ALAssetsLibrary-CustomPhotoAlbum ),讲保存照片做了很好的封装。使用之前记得先导入头文件:
#import "ALAssetsLibrary+CustomPhotoAlbum.h"
保存照片到自己的相簿,直接调用:
1 ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; 2 [library saveImage:self.image toAlbum:@"gang" completion:^(NSURL *assetURL, NSError *error) { 3 if (!error) { 4 5 } 6 } failure:^(NSError *error) { 7 8 }];
ALAssetsLibrary+CustomPhotoAlbum
对保存视频的封装也是非常好的。我现在项目中用的也是这个第三方来保存照片和视频。因为不错,所以推荐给大家使用。
iOS开发——使用技术OC篇&保存(获取)图片到(自定义)相册
标签:
原文地址:http://www.cnblogs.com/iCocos/p/4705585.html