保存到相册步骤:
1.保存图片到【相机胶卷】
2.拥有一个【自定义相册】
3.将刚才保存到【相机胶卷中的图片】引用到【自定义相册】
①保存图片到【相机胶卷】
/* 一、保存图片到【自定义相册】 1.保存图片到【相机胶卷】 1> C语言函数UIImageWriteToSavedPhotosAlbum 2> AssetsLibrary框架 3> Photos框架 2.拥有一个【自定义相册】 1> AssetsLibrary框架 2> Photos框架 3.添加刚才保存的图片到【自定义相册】 1> AssetsLibrary框架 2> Photos框架 */ - (IBAction)save:(UIButton *)sender { /* 保存到相册步骤: 1.保存图片到【相机胶卷】 2.拥有一个【自定义相册】 3.将刚才保存到【相机胶卷中的图片】引用到【自定义相册】 */ UIImageWriteToSavedPhotosAlbum(self.imageView.image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); } - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo { if (error) { [SVProgressHUD showErrorWithStatus:@"保存失败!"]; } else { [SVProgressHUD showSuccessWithStatus:@"保存成功!"]; } }
/* //补充 错误信息:-[NSInvocation setArgument:atIndex:]: index (2) out of bounds [-1, 1] 错误解释:参数越界错误,方法的参数个数和实际传递的参数个数不一致 */
Photos框架详解和保存图片
1.Photos框架详解
/* 二、Photos框架须知 1.PHAsset : 一个PHAsset对象就代表相册中的一张图片或者一个视频 1> 查 : [PHAsset fetchAssets...] 2> 增删改 : PHAssetChangeRequest(包括图片\视频相关的所有改动操作) 2.PHAssetCollection : 一个PHAssetCollection对象就代表一个相册 1> 查 : [PHAssetCollection fetchAssetCollections...] 2> 增删改 : PHAssetCollectionChangeRequest(包括相册相关的所有改动操作) 3.对相片\相册的任何【增删改】操作,都必须放到以下方法的block中执行 -[PHPhotoLibrary performChanges:completionHandler:] -[PHPhotoLibrary performChangesAndWait:error:] */ /* Foundation和Core Foundation的数据类型可以互相转换,比如NSString *和CFStringRef NSString *string = (__bridge NSString *)kCFBundleNameKey; CFStringRef string = (__bridge CFStringRef)@"test"; 获得相机胶卷相册 [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil] */ /* 错误信息:This method can only be called from inside of -[PHPhotoLibrary performChanges:completionHandler:] or -[PHPhotoLibrary performChangesAndWait:error:]
// 异步执行修改操作 [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ [PHAssetChangeRequest creationRequestForAssetFromImage:self.imageView.image]; } completionHandler:^(BOOL success, NSError * _Nullable error) { if (error) { [SVProgressHUD showErrorWithStatus:@"保存失败!"]; } else { [SVProgressHUD showSuccessWithStatus:@"保存成功!"]; } }]; // 同步执行修改操作 NSError *error = nil; [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{ [PHAssetChangeRequest creationRequestForAssetFromImage:self.imageView.image]; } error:&error]; if (error) { [SVProgressHUD showErrorWithStatus:@"保存失败!"]; } else { [SVProgressHUD showSuccessWithStatus:@"保存成功!"]; } */
2.Photos框架保存图片到相机胶卷
- (IBAction)save:(UIButton *)sender { /* 保存到相册步骤: 1.保存图片到【相机胶卷】 2.拥有一个【自定义相册】 3.将刚才保存到【相机胶卷中的图片】引用到【自定义相册】 */ NSError *error = nil; // 保存图片到【相机胶卷】 [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{ [PHAssetChangeRequest creationRequestForAssetFromImage:self.imageView.image]; } error:&error]; if (error) { [SVProgressHUD showErrorWithStatus:@"保存失败!"]; } else { [SVProgressHUD showSuccessWithStatus:@"保存成功!"]; } }
②拥有一个【自定义相册】
Foundation和Core Foundation的数据类型可以互相转换,比如NSString *和CFStringRef
NSString *string = (__bridge NSString *)kCFBundleNameKey;
CFStringRef string = (__bridge CFStringRef)@"test";
1.创建一个【自定义相册】
/** 当前App对应的自定义相册 */ - (PHAssetCollection *)createdCollection; - (IBAction)save:(UIButton *)sender { /* 保存到相册步骤: 1.保存图片到【相机胶卷】 2.拥有一个【自定义相册】 3.将刚才保存到【相机胶卷中的图片】引用到【自定义相册】 */ [self createdCollection]; } #pragma mark - 获得当前App对应的自定义相册 - (PHAssetCollection *)createdCollection { // 获得软件名字 NSString *title = [NSBundle mainBundle].infoDictionary[(__bridge NSString *)kCFBundleNameKey]; // 抓取所有的自定义相册 PHFetchResult<PHAssetCollection *> *collections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil]; // 查找当前App对应的自定义相册 for (PHAssetCollection *collection in collections) { if ([collection.localizedTitle isEqualToString:title]) { return collection; } } /** 当前App对应的自定义相册没有被创建过 **/ // 创建一个【自定义相册】 NSError *error = nil; __block NSString *createdCollectionID = nil; [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
createdCollectionID = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title].placeholderForCreatedAssetCollection.localIdentifier; } error:&error]; if (error) { [SVProgressHUD showErrorWithStatus:@"创建相册失败!"]; return nil; } // 根据唯一标识获得刚才创建的相册 return [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[createdCollectionID] options:nil].firstObject; } /* Foundation和Core Foundation的数据类型可以互相转换,比如NSString *和CFStringRef NSString *string = (__bridge NSString *)kCFBundleNameKey; CFStringRef string = (__bridge CFStringRef)@"test"; 获得相机胶卷相册 [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil] */
2.获取相册
#pragma mark - 获得当前App对应的自定义相册 // 根据唯一标识获得刚才创建的相册 return [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[createdCollectionID] options:nil].firstObject;
3.保存图片到自定义相册
/** 当前App对应的自定义相册 */ - (PHAssetCollection *)createdCollection; /** 返回刚才保存到【相机胶卷】的图片 */ - (PHFetchResult<PHAsset *> *)createdAssets; - (IBAction)save:(UIButton *)sender { PHAuthorizationStatus oldStatus = [PHPhotoLibrary authorizationStatus]; // 请求\检查访问权限 : // 如果用户还没有做出选择,会自动弹框,用户对弹框做出选择后,才会调用block // 如果之前已经做过选择,会直接执行block [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) { dispatch_async(dispatch_get_main_queue(), ^{ if (status == PHAuthorizationStatusDenied) { // 用户拒绝当前App访问相册 if (oldStatus != PHAuthorizationStatusNotDetermined) { HKLog(@"提醒用户打开开关") } } else if (status == PHAuthorizationStatusAuthorized) { // 用户允许当前App访问相册 [self saveImageIntoAlbum]; } else if (status == PHAuthorizationStatusRestricted) { // 无法访问相册 [SVProgressHUD showErrorWithStatus:@"因系统原因,无法访问相册!"]; } }); }]; } /** * 保存图片到相册 */ - (void)saveImageIntoAlbum { // 获得相片 PHFetchResult<PHAsset *> *createdAssets = self.createdAssets; if (createdAssets == nil) { [SVProgressHUD showErrorWithStatus:@"保存图片失败!"]; return; } // 获得相册 PHAssetCollection *createdCollection = self.createdCollection; if (createdCollection == nil) { [SVProgressHUD showErrorWithStatus:@"创建或者获取相册失败!"]; return; } // 添加刚才保存的图片到【自定义相册】 NSError *error = nil; [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{ PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:createdCollection]; [request insertAssets:createdAssets atIndexes:[NSIndexSet indexSetWithIndex:0]]; } error:&error]; // 最后的判断 if (error) { [SVProgressHUD showErrorWithStatus:@"保存图片失败!"]; } else { [SVProgressHUD showSuccessWithStatus:@"保存图片成功!"]; } } #pragma mark - 获得当前App对应的自定义相册 - (PHAssetCollection *)createdCollection { // 获得软件名字 NSString *title = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"]; // 抓取所有的自定义相册 PHFetchResult<PHAssetCollection *> *collections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil]; // 查找当前App对应的自定义相册 for (PHAssetCollection *collection in collections) { if ([collection.localizedTitle isEqualToString:title]) { return collection; } } /** 当前App对应的自定义相册没有被创建过 **/ // 创建一个【自定义相册】 NSError *error = nil; __block NSString *createdCollectionID = nil; [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{ createdCollectionID = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title].placeholderForCreatedAssetCollection.localIdentifier; } error:&error]; if (error) return nil; // 根据唯一标识获得刚才创建的相册 return [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[createdCollectionID] options:nil].firstObject; } - (PHFetchResult<PHAsset *> *)createdAssets { NSError *error = nil; __block NSString *assetID = nil; // 保存图片到【相机胶卷】 [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{ assetID = [PHAssetChangeRequest creationRequestForAssetFromImage:self.imageView.image].placeholderForCreatedAsset.localIdentifier; } error:&error]; if (error) return nil; // 获取刚才保存的相片 return [PHAsset fetchAssetsWithLocalIdentifiers:@[assetID] options:nil]; } //补充:不带权限判断 //- (IBAction)save { // NSError *error = nil; // // // 保存图片到【相机胶卷】 // __block PHObjectPlaceholder *placeholder = nil; // [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{ // placeholder = [PHAssetChangeRequest creationRequestForAssetFromImage:self.imageView.image].placeholderForCreatedAsset; // } error:&error]; // if (error) { // [SVProgressHUD showErrorWithStatus:@"保存图片失败!"]; // return; // } // // // 获得相册 // PHAssetCollection *createdCollection = self.createdCollection; // if (createdCollection == nil) { // [SVProgressHUD showErrorWithStatus:@"创建相册失败!"]; // return; // } // // // 添加刚才保存的图片到【自定义相册】 // [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{ // PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:createdCollection]; // [request insertAssets:@[placeholder] atIndexes:[NSIndexSet indexSetWithIndex:0]]; // } error:&error]; // // // 最后的判断 // if (error) { // [SVProgressHUD showErrorWithStatus:@"保存图片失败!"]; // } else { // [SVProgressHUD showSuccessWithStatus:@"保存图片成功!"]; // } //}