美文网首页系统相册iOS_Dev图像处理
iOS 开发之照片框架PhotoKit

iOS 开发之照片框架PhotoKit

作者: charlotte2018 | 来源:发表于2017-02-17 16:07 被阅读425次

    背景:最近项目要做一个类似系统相册的功能,例如咱们的app拍的照片保存在了自定义的相册中,然后去用我写的这个相册去展示它。本文主要是如何使用PhotoKit框架访问系统的相册、照片,因为这个框架是iOS8出来的,所以不支持iOS7😯。

    下面看我封装的这个访问系统相册的框架

    //
    //  YBSystemPhotoTool.h
    //  sway
    //
    //  Created by wyb on 2017/2/16.
    //  Copyright © 2017年 xxx. All rights reserved.
    //
    
    //此工具支持iOS8.0及以上
    #import <Foundation/Foundation.h>
    #import <Photos/Photos.h>
    
    //相册的model
    @interface YBPhotoAblumModel : NSObject
    
    @property (nonatomic, copy) NSString *title; //相册名字
    @property (nonatomic, assign) NSInteger count; //该相册内相片数量
    @property (nonatomic, strong) PHAsset *headImageAsset; //相册第一张图片缩略图
    @property (nonatomic, strong) PHAssetCollection *assetCollection; //相册集,通过该属性获取该相册集下所有照片
    
    @end
    
    /*---------------------------------------分割线-------------------------------------------*/
    
    @interface YBSystemPhotoTool : NSObject
    
    + (instancetype)sharePhotoTool;
    
    /**
     * @brief 获取用户所有相册列表
     */
    - (NSArray<YBPhotoAblumModel *> *)getPhotoAblumList;
    
    
    /**
     * @brief 获取相册内所有图片资源
     * @param ascending 是否按创建时间正序排列 YES,创建时间正(升)序排列; NO,创建时间倒(降)序排列
     */
    - (NSArray<PHAsset *> *)getAllAssetInPhotoAblumWithAscending:(BOOL)ascending;
    
    
    /**
     * @brief 获取指定相册内的所有图片
     */
    - (NSArray<PHAsset *> *)getAssetsInAssetCollection:(PHAssetCollection *)assetCollection ascending:(BOOL)ascending;
    
    
    /**
     * @brief 获取每个Asset对应的图片
     */
    - (void)requestImageForAsset:(PHAsset *)asset size:(CGSize)size resizeMode:(PHImageRequestOptionsResizeMode)resizeMode completion:(void (^)(UIImage *image))completion;
    
    
    /**
     删除系统相册中的照片,单个或者多个
    
     @param assets 要删除的照片数组
     @param completionHandler 成功的回调
     */
    - (void)deleteSystemPhothWithPhotos:(NSArray<PHAsset *>*)assets successHandler:(dispatch_block_t)completionHandler;
    
    #pragma mark - 判断软件是否有相册访问权限
    + (BOOL)judgeIsHavePhotoAblumAuthority;
    
    #pragma mark - 判断软件是否有相机访问权限
    + (BOOL)judgeIsHaveCameraAuthority;
    
    @end
    
    
    //
    //  YBSystemPhotoTool.m
    //  sway
    //
    //  Created by wyb on 2017/2/16.
    //  Copyright © 2017年 xxx. All rights reserved.
    //
    
    #import "YBSystemPhotoTool.h"
    
    @implementation YBPhotoAblumModel
    
    @end
    
    /*---------------------------------------分割线-------------------------------------------*/
    
    
    @implementation YBSystemPhotoTool
    
    static YBSystemPhotoTool *sharePhotoTool = nil;
    + (instancetype)sharePhotoTool
    {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            sharePhotoTool = [[self alloc] init];
        });
        return sharePhotoTool;
    }
    
    + (instancetype)allocWithZone:(struct _NSZone *)zone
    {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            sharePhotoTool = [super allocWithZone:zone];
        });
        return sharePhotoTool;
    }
    
    #pragma mark - 获取所有相册列表
    - (NSArray<YBPhotoAblumModel *> *)getPhotoAblumList
    {
        NSMutableArray<YBPhotoAblumModel *> *photoAblumList = [NSMutableArray array];
        
        //获取所有智能相册
        PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
        [smartAlbums enumerateObjectsUsingBlock:^(PHAssetCollection * _Nonnull collection, NSUInteger idx, BOOL *stop) {
            //过滤掉视频和最近删除
            if (!([collection.localizedTitle isEqualToString:@"Recently Deleted"] ||
                  [collection.localizedTitle isEqualToString:@"Videos"])) {
                NSArray<PHAsset *> *assets = [self getAssetsInAssetCollection:collection ascending:NO];
                if (assets.count > 0) {
                    YBPhotoAblumModel *ablum = [[YBPhotoAblumModel alloc] init];
                    ablum.title = [self transformAblumTitle:collection.localizedTitle];
                    ablum.count = assets.count;
                    ablum.headImageAsset = assets.firstObject;
                    ablum.assetCollection = collection;
                    [photoAblumList addObject:ablum];
                }
            }
        }];
        
        //获取用户创建的相册
        PHFetchResult *userAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil];
        [userAlbums enumerateObjectsUsingBlock:^(PHAssetCollection * _Nonnull collection, NSUInteger idx, BOOL * _Nonnull stop) {
            NSArray<PHAsset *> *assets = [self getAssetsInAssetCollection:collection ascending:NO];
            if (assets.count > 0) {
                YBPhotoAblumModel *ablum = [[YBPhotoAblumModel alloc] init];
                ablum.title = collection.localizedTitle;
                ablum.count = assets.count;
                ablum.headImageAsset = assets.firstObject;
                ablum.assetCollection = collection;
                [photoAblumList addObject:ablum];
            }
        }];
        
        return photoAblumList;
    }
    
    - (NSString *)transformAblumTitle:(NSString *)title
    {
        if ([title isEqualToString:@"Slo-mo"]) {
            return @"慢动作";
        } else if ([title isEqualToString:@"Recently Added"]) {
            return @"最近添加";
        } else if ([title isEqualToString:@"Favorites"]) {
            return @"最爱";
        } else if ([title isEqualToString:@"Recently Deleted"]) {
            return @"最近删除";
        } else if ([title isEqualToString:@"Videos"]) {
            return @"视频";
        } else if ([title isEqualToString:@"All Photos"]) {
            return @"所有照片";
        } else if ([title isEqualToString:@"Selfies"]) {
            return @"自拍";
        } else if ([title isEqualToString:@"Screenshots"]) {
            return @"屏幕快照";
        } else if ([title isEqualToString:@"Camera Roll"]) {
            return @"相机胶卷";
        } else if ([title isEqualToString:@"Panoramas"]) {
            return @"全景照片";
        }
        return nil;
    }
    
    - (PHFetchResult *)fetchAssetsInAssetCollection:(PHAssetCollection *)assetCollection ascending:(BOOL)ascending
    {
        PHFetchOptions *option = [[PHFetchOptions alloc] init];
        option.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:ascending]];
        PHFetchResult *result = [PHAsset fetchAssetsInAssetCollection:assetCollection options:option];
        return result;
    }
    
    #pragma mark - 获取相册内所有照片资源
    - (NSArray<PHAsset *> *)getAllAssetInPhotoAblumWithAscending:(BOOL)ascending
    {
        NSMutableArray<PHAsset *> *assets = [NSMutableArray array];
        
        PHFetchOptions *option = [[PHFetchOptions alloc] init];
        //ascending 为YES时,按照照片的创建时间升序排列;为NO时,则降序排列
        option.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:ascending]];
        
        PHFetchResult *result = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:option];
        
        [result enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            PHAsset *asset = (PHAsset *)obj;
            [assets addObject:asset];
        }];
        
        return assets;
    }
    
    #pragma mark - 获取指定相册内的所有图片
    - (NSArray<PHAsset *> *)getAssetsInAssetCollection:(PHAssetCollection *)assetCollection ascending:(BOOL)ascending
    {
        NSMutableArray<PHAsset *> *arr = [NSMutableArray array];
        
        PHFetchResult *result = [self fetchAssetsInAssetCollection:assetCollection ascending:ascending];
        [result enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            if (((PHAsset *)obj).mediaType == PHAssetMediaTypeImage) {
                [arr addObject:obj];
            }
        }];
        return arr;
    }
    
    #pragma mark - 获取asset对应的图片
    - (void)requestImageForAsset:(PHAsset *)asset size:(CGSize)size resizeMode:(PHImageRequestOptionsResizeMode)resizeMode completion:(void (^)(UIImage *))completion
    {
        PHImageRequestOptions *option = [[PHImageRequestOptions alloc] init];
        /**
         resizeMode:对请求的图像怎样缩放。有三种选择:None,默认加载方式;Fast,尽快地提供接近或稍微大于要求的尺寸;Exact,精准提供要求的尺寸。
         deliveryMode:图像质量。有三种值:Opportunistic,在速度与质量中均衡;HighQualityFormat,不管花费多长时间,提供高质量图像;FastFormat,以最快速度提供好的质量。
         这个属性只有在 synchronous 为 true 时有效。
         */
        option.resizeMode = resizeMode;//控制照片尺寸
        //option.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;//控制照片质量
        //option.synchronous = YES;
        option.networkAccessAllowed = YES;
        //param:targetSize 即你想要的图片尺寸,若想要原尺寸则可输入PHImageManagerMaximumSize
        [[PHCachingImageManager defaultManager] requestImageForAsset:asset targetSize:size contentMode:PHImageContentModeAspectFit options:option resultHandler:^(UIImage * _Nullable image, NSDictionary * _Nullable info) {
            completion(image);
        }];
    }
    
    - (void)deleteSystemPhoth:(dispatch_block_t)changeBlock completionHandler:(nullable void(^)(BOOL success, NSError *__nullable error))completionHandler{
        
        [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
            
            changeBlock();
            
        } completionHandler:^(BOOL success, NSError * _Nullable error) {
            
            completionHandler(success,error);
        }];
    }
    
    
    
    - (void)deleteSystemPhothWithPhotos:(NSArray<PHAsset *>*)assets successHandler:(dispatch_block_t)completionHandler{
        
        [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
            
            [PHAssetChangeRequest deleteAssets:assets];
            
        } completionHandler:^(BOOL success, NSError *error) {
            
            if (success == YES) {
                
                completionHandler();
            }
            
            
        }];
        
       
    }
    
    #pragma mark - 判断软件是否有相册访问权限
    + (BOOL)judgeIsHavePhotoAblumAuthority
    {
        PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
        if (status == PHAuthorizationStatusRestricted ||
            status == PHAuthorizationStatusDenied) {
            return NO;
        }
        return YES;
    }
    
    #pragma mark - 判断软件是否有相机访问权限
    + (BOOL)judgeIsHaveCameraAuthority
    {
        AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
        if (status == AVAuthorizationStatusRestricted ||
            status == AVAuthorizationStatusDenied) {
            return NO;
        }
        return YES;
    }
    
    
    @end
    
    
    • 系统的相册


      084573F1-7140-4033-8A18-D3DF1E75CB1D.png
    • 点击查看大图


      QQ20170226-173918@2x.png
    • demo地址在这里哦

    自定义相册的使用

    #import "ViewController.h"
    #import <Photos/Photos.h>
    
    /** 相册名字 */
    static NSString * const CollectionName = @"wyb-photo";
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        [self searchAllImages];
    }
    
    #pragma mark - 查询相册中的图片
    /**
     * 查询所有的图片
     */
    - (IBAction)searchAllImages {
        // 判断授权状态
        [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
            if (status != PHAuthorizationStatusAuthorized) return;
            
            dispatch_async(dispatch_get_main_queue(), ^{
                // 遍历所有的自定义相册
                PHFetchResult<PHAssetCollection *> *collectionResult0 = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
                for (PHAssetCollection *collection in collectionResult0) {
                    [self searchAllImagesInCollection:collection];
                }
                
                // 获得相机胶卷的图片
                PHFetchResult<PHAssetCollection *> *collectionResult1 = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
                for (PHAssetCollection *collection in collectionResult1) {
                    if (![collection.localizedTitle isEqualToString:@"Camera Roll"]) continue;
                    [self searchAllImagesInCollection:collection];
                    break;
                }
            });
        }];
    }
    
    /**
     * 查询某个相册里面的所有图片
     */
    - (void)searchAllImagesInCollection:(PHAssetCollection *)collection
    {
        // 采取同步获取图片(只获得一次图片)
        PHImageRequestOptions *imageOptions = [[PHImageRequestOptions alloc] init];
        imageOptions.synchronous = YES;
        
        NSLog(@"相册名字:%@", collection.localizedTitle);
        
        // 遍历这个相册中的所有图片
        PHFetchResult<PHAsset *> *assetResult = [PHAsset fetchAssetsInAssetCollection:collection options:nil];
        for (PHAsset *asset in assetResult) {
            // 过滤非图片
            if (asset.mediaType != PHAssetMediaTypeImage) continue;
            
            // 图片原尺寸
            CGSize targetSize = CGSizeMake(asset.pixelWidth, asset.pixelHeight);
            // 请求图片
            [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:targetSize contentMode:PHImageContentModeDefault options:imageOptions resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
                NSLog(@"图片:%@ %@", result, [NSThread currentThread]);
            }];
        }
    }
    
    #pragma mark - 保存图片到自定义相册
    /**
     * 获得自定义的相册对象
     */
    - (PHAssetCollection *)collection
    {
        // 先从已存在相册中找到自定义相册对象
        PHFetchResult<PHAssetCollection *> *collectionResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
        for (PHAssetCollection *collection in collectionResult) {
            if ([collection.localizedTitle isEqualToString:CollectionName]) {
                return collection;
            }
        }
        
        // 新建自定义相册
        __block NSString *collectionId = nil;
        NSError *error = nil;
        [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
            collectionId = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:CollectionName].placeholderForCreatedAssetCollection.localIdentifier;
        } error:&error];
        
        if (error) {
            NSLog(@"获取相册【%@】失败", CollectionName);
            return nil;
        }
        
        return [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[collectionId] options:nil].lastObject;
    }
    
    /**
     * 保存图片到相册
     */
    - (IBAction)saveImage {
        // 判断授权状态
        [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
            if (status != PHAuthorizationStatusAuthorized) return;
            
            dispatch_async(dispatch_get_main_queue(), ^{
                NSError *error = nil;
        
                // 保存相片到相机胶卷
                __block PHObjectPlaceholder *createdAsset = nil;
                [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
                    createdAsset = [PHAssetCreationRequest creationRequestForAssetFromImage:[UIImage imageNamed:@"logo"]].placeholderForCreatedAsset;
                } error:&error];
                
                if (error) {
                    NSLog(@"保存失败:%@", error);
                    return;
                }
                
                // 拿到自定义的相册对象
                PHAssetCollection *collection = [self collection];
                if (collection == nil) return;
                
                [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
                    [[PHAssetCollectionChangeRequest changeRequestForAssetCollection:collection] insertAssets:@[createdAsset] atIndexes:[NSIndexSet indexSetWithIndex:0]];
                } error:&error];
                
                if (error) {
                    NSLog(@"保存失败:%@", error);
                } else {
                    NSLog(@"保存成功");
                }
            });
        }];
    }
    
    @end
    
    

    相关文章

      网友评论

      本文标题:iOS 开发之照片框架PhotoKit

      本文链接:https://www.haomeiwen.com/subject/swklwttx.html