一、保存图片到【相机胶卷】
方法一:C语言函数
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UIImageWriteToSavedPhotosAlbum(self.img, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
}
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
if (error) {
NSLog(@"保存失败");
} else {
NSLog(@"保存成功");
}
}
方法二:AssetsLibrary 框架
作为一套老框架,AssetsLibrary 不但有坑,而且还不少。比如,AssetsLibrary 实例需要强引用,遵循写入优先原则…现在已经被 Photos 框架代替,这里就不做介绍。
方法三:Photos 框架 —— #import <Photos/Photos.h>
// 异步执行修改操作
// 在这里保存图片到相册
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
[PHAssetChangeRequest creationRequestForAssetFromImage:self.img];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (error) {
NSLog(@"保存失败");
} else {
NSLog(@"保存成功");
}
}];
// 同步执行修改操作
NSError *error = nil;
[[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
[PHAssetChangeRequest creationRequestForAssetFromImage:self.img];
} error:&error];
if (error) {
NSLog(@"保存失败");
} else {
NSLog(@"保存成功");
}
二、保存图片到【自定义相册】
Photos 框架基本方法概况
PHAsset:一个 PHAsset 对象就代表相册中的一张图片或者视频
查:[PHAsset fetchAssets…]
增删改:[PHAssetChangeRequest creation…/delete…]
PHAssetCollection:一个 PHAssetCollection 代表一个相册
查:[PHAssetCollection fetchAssetCollections…]
增删改:[PHAssetCollectionChangeRequest creation…/delete…]
方法步骤
- 0.判断相册权限
PHAuthorizationStatus oldStatus = [PHPhotoLibrary authorizationStatus];
// 如果用户还没有做出选择,会自动弹框,用户对弹框做出选择后,才会调用block
// 如果之前已经做过选择,会直接执行block
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
// block中是在子线程中进行,如果刷新UI需要回到主线程
dispatch_async(dispatch_get_main_queue(), ^{
if (status == PHAuthorizationStatusDenied) {
NSLog(@"用户拒绝当前APP访问相册");
// 如果状态不等于没有做决定
if (oldStatus != PHAuthorizationStatusNotDetermined) {
NSLog(@"提醒用户打开开关");
}
} else if (status == PHAuthorizationStatusAuthorized) {
NSLog(@"用户允许当前APP访问相册");
} else if (status == PHAuthorizationStatusRestricted) {
NSLog(@"无法访问相册");
}
});
}];
- 1.保存图片到【相机胶卷】
NSError *error = nil;
__block NSString *assetID = nil; // 图片的ID
[[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
assetID = [PHAssetChangeRequest creationRequestForAssetFromImage:image].placeholderForCreatedAsset.localIdentifier;
} error:&error];
if (error) {
NSLog(@"MYPhotoTool - 保存失败");
}
- 2.拥有一个【自定义相册】
// 获取软件名字
NSString *title = [NSBundle mainBundle].infoDictionary[(NSString *)kCFBundleNameKey];
// 获取所有自定义相册
PHFetchResult<PHAssetCollection *> *collections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
// 查找当前APP对应的自定义相册
for (PHAssetCollection *collection in collections) {
// *** 如果存在自定义相册
if ([collection.localizedTitle isEqualToString:collectionName]) {
return collection;
}
}
// *** 自定义相册没有被创建过
__block NSString *ID = nil;
NSError *error = nil;
[[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
// 创建一个【自定义相册】
PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:collectionName];
// 获取站位标识
ID = request.placeholderForCreatedAssetCollection.localIdentifier;
} error:&error];
if (error) {
NSLog(@"MYPhotoTool - 创建自定义相册失败");
return nil;
}
// 根据站位标识获取当前APP对应的自定义相册
PHAssetCollection *collection = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[ID] options:nil].firstObject;
- 3.添加刚才保存的图片到【自定义相册】
NSError *error = nil;
[[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:collection];
id<NSFastEnumeration> assetIDs = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetID] options:nil];
[request insertAssets:assetIDs atIndexes:[NSIndexSet indexSetWithIndex:0]];
} error:&error];
if (error) {
NSLog(@"MYPhotoTool - 保存失败");
}
三、选择照片到项目中
1.从相册中选择照片
- UIImagePickerController(自带选择界面)(只能选择单张图片)
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
picker.delegate = self; // <UINavigationControllerDelegate, UIImagePickerControllerDelegate>
[self presentViewController:picker animated:YES completion:nil];
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
[picker dismissViewControllerAnimated:YES completion:nil];
self.imgView.image = info[UIImagePickerControllerOriginalImage];
}
AssetsLibrary 框架
Photos 框架
网上基于 Photos 框架的三方框架一搜一大堆,就不浪费时间造轮子了。其实是最近项目太紧了,没时间弄,等年后抽时间把这部分补充一下吧。
2.选择相机拍摄的照片
UIImagePickerController(自带选择界面)
和从相册中选择照片一样,改变 sourceType 就可以了
AVCaptureSession ——
#import <AVFoundation/AVFoundation.h>
保存图片到【相机胶卷】和【自定义相册】框架和 DEMO 已经上传到 github ,下载地址:MYPhotoTool