杂的文iOS Developer

保存图片到自定义相册中

2016-10-27  本文已影响172人  追风筝的boy
Snip20161027_3.png
<key>NSPhotoLibraryUsageDescription</key> 
<string>"App名称(写你需要的名称)"需要您的同意,才能访问相册</string>

保存照片到系统的相册中(非常easy)

/**
 将照片写入到系统相册中

 @param image            需要保存的照片
 @param completionTarget 保存完成时的消息调用者
 @param completionSel    保存完成时需要调用的方法(必须使用系统提供的方法)
 */
UIImageWriteToSavedPhotosAlbum(UIImage *image, id completionTarget, SEL completionSel;

// 上面的方法中必须使用这个方法,来作为SEL类型的参数
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo


// 点击保存按钮, 将图片存入到系统相册中
- (void)save
{
    UIImageWriteToSavedPhotosAlbum(_imageView.image, self, @selector(imagePickerController:didFinishPickingMediaWithInfo:), nil);
}

- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
    if (error) {
        NSLog(@"提醒用户保存失败--%@", error.description);
    } else {
        NSLog(@"提醒用户保存成功");
    }
}

保存照片到系统相册(稍微复杂了那么一丢丢)

Photos/Photos.h框架中我们需要使用的类的简单介绍

PHPhotoLibrary(相簿类)
You use the shared photo library object to get the user' s permission for your app to access Photos content, to perform changes to assets and collections, and to register for update messages sent when the Photos library changes

使用这个类的一个单粒对象,用于得到用户的许可来让你的app访问手机的相簿里面的内容,也可以用于修改相簿中的图片和相册,也可以通过注册来监听相簿内容的改变.

PHAsset(资源类,图片,视频,或者动态照片资源)
A representation of an image, video or Live Photo in the Photos library.

在相簿中代表一张图片, 一段视频, 或者一张动态照片

PHAssetChangeRequest(操作资源的请求类)
A request to create, delete, change metadata for, or edit the content of a Photos asset, for use in a photo library change block.
一个请求用于创建,删除和修改图片的.或者用于编辑图片,必须在PHPhotoLibrary这个类的对象方法- (void)performChanges:(dispatch_block_t)changeBlock completionHandler:(nullable void(^)(BOOL success, NSError *__nullable error))completionHandler 方法中使用

PHAssetCollection(相册类)
A representation of a Photos asset grouping, such as a moment, user-created album, or smart album.

在相簿中用于表示一组图片,例如系统根据时间创建的相册,以及用户自己创建的相册,以及智能相册

PHAssetCollectionChangeRequest(操作相册的请求类)
A request to create, delete, or modify a Photos asset collection, for use in a photo library change block.

一个请求对象,用于创建,删除和修改一个相册,必须在`PHPhotoLibrary`这个类的对象方法- (void)performChanges:(dispatch_block_t)changeBlock completionHandler:(nullable void(^)(BOOL success, NSError *__nullable error))completionHandler 方法中使用

PHObjectPlaceholder(资源的代理类,等同于资源对象)
A read-only proxy representing a Photos asset or collection object yet to be created by a change request.

一个只读属性,通过一个改变请求(changeReques)来创建的,用于表示一张图片对象或者一个相册对象的代理

PHFetchResult(用于获取资源或者相册的类)
An ordered list of assets or collections returned from a Photos fetch method.

通过一个fetch开头的方法获取的一组有序的图片或者相册(可以理解为一个数组)

思路

代码思路

// 通过该方法创建一个自定义的相册
PHAssetCollectionChangeRequest *assetCollectionChangRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:@"自定义相册名称"];
// 传入一个UIImage的图片
PHAssetChangeRequest *assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:_imageView.image];

// 创建占位图片
PHObjectPlaceholder *assetPlaceholder = [assetChangeRequest placeholderForCreatedAsset];
// 存入占位图片到自定义相册中
[assetCollectionChangRequest addAssets:@[assetPlaceholder]];

}
```

- 获取到当前的授权状态,根据不同的状态进行处理

```objc
    // 获取当前的授权状态
PHAuthorizationStatus authorizationStatus = [PHPhotoLibrary authorizationStatus];
if (authorizationStatus == PHAuthorizationStatusNotDetermined) { 
    // 如果没有授权,那么我们需要向用户请求授权
    [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
        if (status == PHAuthorizationStatusAuthorized) {
                // 授权成功, 直接保存图片
        } else {
            // 授权失败,我们需要提示用户,请到 设置 -> 应用名 -> 相册 -> ON 来开启相册授权
        }
    }];
} else if (authorizationStatus == PHAuthorizationStatusAuthorized) {
    // 已经授权成功,直接保存图片
} else {
    // 没有授权
    // 我们需要提醒用户, 请到 设置 -> 应用名 -> 相册 -> ON 来开启相册授权
}

```
// 在外界,我们只需要调用该方法,判断是否有值,即可判断当前的相册是否存在.
// 获取指定名称的相册
- (PHAssetCollection *)customAlbumForTitle:(NSString *)albumTitle
{
    // 1.获取所有自定义的相册
    PHFetchResult *result = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
    // 2.遍历相册,判断是否有同名的相册
    for (PHAssetCollection *assetCollection in result) {
        if ([assetCollection.localizedTitle isEqualToString:JGPhotoAlbumTitle]) {
        // 2.1 有同名相册,直接将这个相册返回
            return assetCollection;
        }
    }
    return nil;
}

最终方案

// SVProgressHUD是一个第三方框架,比较好用
// 该方法为点击保存图片按钮的时候调用
// 主要实现了判断当前授权状态,并执行不同操作
- (IBAction)save:(id)sender {

    // 获取当前的授权状态
    PHAuthorizationStatus authorizationStatus = [PHPhotoLibrary authorizationStatus];
    
    if (authorizationStatus == PHAuthorizationStatusNotDetermined) { // 授权状态为确定
        // 请求授权
        [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
            if (status == PHAuthorizationStatusAuthorized) {
                [self savePhotos];
            } else {
                [SVProgressHUD setMinimumDismissTimeInterval:1.0];
                [SVProgressHUD showErrorWithStatus:@"请到 设置 -> 应用名 -> 相册 -> ON 来开启相册授权"];
            }
        }];
    } else if (authorizationStatus == PHAuthorizationStatusAuthorized) {
        [self savePhotos];
    } else {
        
        [SVProgressHUD setMinimumDismissTimeInterval:1.0];
        [SVProgressHUD showErrorWithStatus:@"请到 设置 -> 应用名 -> 相册 -> ON 来开启相册授权"];
    }
}

// 保存图片到自定义相册的具体实现
- (void)savePhotos
{

    // 将图片保存到自定义的相册 PHPhotoLibrary PHAssetCollectionChangeRequest
    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
    
        // 1.自定义相册
        // 1.1 获取指定名称的相册对象
        PHAssetCollection *assetCollection = [self customAlbumForTitle:JGPhotoAlbumTitle];
        
        PHAssetCollectionChangeRequest *assetCollectionChangRequest;
        // 1.2如果存在, 那么直接拿到这个相册,创建一个修改相册请求
        if (assetCollection) {
            assetCollectionChangRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection];
        } else {
            // 1.3如果没有,自己创建一个相册,并创建修改相册请求
            assetCollectionChangRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:JGPhotoAlbumTitle];
        }
        
        // 2.将照片保存到系统的相册中,并创建一个改变图片的请求对象
        PHAssetChangeRequest *assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:self.imageView.image];
        
        // 3.将系统中的相册保存到自定义相册中
        PHObjectPlaceholder *assetPlaceholder = [assetChangeRequest placeholderForCreatedAsset];
        [assetCollectionChangRequest addAssets:@[assetPlaceholder]];
        
    } completionHandler:^(BOOL success, NSError * _Nullable error) { // 当操作执行完毕
        
        if (error) { // 保存不成功
            [SVProgressHUD setMinimumDismissTimeInterval:1.0];
            [SVProgressHUD showErrorWithStatus:@"保存失败"];
        } else { // 保存成功
            [SVProgressHUD setMinimumDismissTimeInterval:1.0];
            [SVProgressHUD showSuccessWithStatus:@"保存成功"];
        }
    }];

}

// 获取指定名称的相册
- (PHAssetCollection *)customAlbumForTitle:(NSString *)albumTitle
{
    // 首先判断当前的相册是否已经创建
    PHFetchResult *result = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
    
    for (PHAssetCollection *assetCollection in result) {
        if ([assetCollection.localizedTitle isEqualToString:JGPhotoAlbumTitle]) {
            return assetCollection;
        }
    }
    return nil;
}

上一篇下一篇

猜你喜欢

热点阅读