美文网首页收藏ios
Photos中常用类(获取展示功能相关)简介

Photos中常用类(获取展示功能相关)简介

作者: 范哥编程 | 来源:发表于2017-06-22 19:51 被阅读199次

    简介

    Photos framework是iOS8苹果提供的新的图片框架,能直接获取图片和视频,包括iCloud上面的图库。使用这个框架可以获取assets来展示和回放,编辑图片或者视频内容,或者使用系统相册、时刻、和分享到iCloud的相册来进行相关操作,本文侧重相片的获取与保存。

    demo地址在这里

    新特性与一些概念

    获取实体&改变请求

    Photos framework中的三个model类:PHAsset,PHAssetCollection,PHCollectionList,分别对应三个类型的实体:asset(图片和视频),assets集合(相册和时刻),集合列表(相册文件夹或者moment clusters)。这些对象,也成为 相片实体(photo entities),只包含元数据,同时也是read-only属性。

    改变观察机制

    使用这个特性能够在其他app、设备更改了图片和视频内容或者相册的时候通知你的app,在实现观察机制前需要用PHPhotoLibrary对象先为你获取到的照片实体注册一个观察者

    支持手机中的照片app的特性

    使用PHCollectionList类查找获取照片中响应的时刻层级asset,使用PHAsset标记连拍照片,全景照片和高分辨率视频等。当开启iCloud图库后,Photo framework能从iCloud中获取到使用相同apple ID登陆的不同设备中的照片。

    加载缓存asset和缩略图

    使用PHImageManager请求asset中的特定尺寸的图片或者通过AV Foundation 对象获取video asset。Photos frame会根据设定自动下载,缓存,以便于高效复用。对于大量的assets的快速执行,例如在生成相册中所有图片的缩略图时,使用PHCachingImageManager的子类来实现。

    编辑asset内容

    PHAsset和PHAsssetChangeRequest定义了一些用于编辑照片或者视频内容的方法,同时允许将编辑后的图片保存到图库中。为了可以让用户可以在前次修改的基础上再次修改,或者是在不同的app上进行多次修改,Photos保存了当前和县区版本的asset,如果单独使用PHAdjustMnentData对象只能获取到最后编辑的照片。如果你的app支持在前面修改基础上多次编辑,你应该允许用户撤回或者修改本次编辑。

    framework中的类

    PHAdjustmentData

    当修改了一个asset后,Photos会将PHAdjustmentData对象和修改过的图片或者视频数据一起保存起来,你可以通过这个对象提供的一些数据来修改已经保存的编辑。

    当需要调整data的时候,调用

    -(PHContentEditingInputRequestID)requestContentEditingInputWithOptions:(PHContentEditingInputRequestOptions*)optionscompletionHandler:(void(^)(PHContentEditingInput *contentEditingInput, NSDictionary *info))completionHandler

    初始化方法:

    /** *  用于标记特定的修改数据,使用formatIndentifier和formatVersion指定唯一的adjustment, *data存储用于回滚到之前状态的数据,也就是当前图片的修改数据,以便于在这个基础上继续进行修改* *  @param formatIndentifier 用于标记 adjustmentdata*  @param formatVersion    version number for adjustmentdata*  @paramdata包含了重新修改需要的数据* */- (instanceType)initWithForamtIndentifier:(NSString*)formatIndentifier                            formatVersion:(NSString*)formatVersiondata:(NSData*)data;

    PHAssetChangeRequest

    在图库中使用PHAssetChangeRequest对象来创建,修改,删除PHAsset对象。

    可以使用适当的类方法来实现增加删除修改asset的目的:

    /**

    *  删除给定的assets

    *

    *  @param assets 包含需要删除的asset数组

    */+ (void)deleteAssets:(id)assets;/**

    *  修改给定的PHAsset对象

    *

    *  在修改之前使用 'canPerformEditOperation:' 方法判断asset是否允许修改

    *  在photo library change block中创建修改请求后,设置正确的修改请求属性。

    *

    *  @param asset 待修改的asset

    */+ (instancetype)changeRequestForAsset:(PHAsset *)asset;

    PHFetchOptions

    当你使用没方法获取PHAsset(图片和视频),PHCollection(相册类型),PHAssetCollection(相册)的实体(相当于包含多个数据的模型)使用PHFetchOptions对象指定操作,例如获取的实体的排列属性等。

    调用PHFetchRequest类方法创建一个包含fetch请求的对象。

    这个类包含了两个属性:predicate和sortDescriptors。

    NSPredicate *predicate:

    specifies which properties to select results by and that also specifies any constraints on selection.

    用于指定返回的结果和指定条件

    示例:

    PHFetchOperation *fetchOptions = [PHFetchOptionnew];fetchOperations.predicate = [NSPredicatepredicateWithFormat:@"(mediaSubtype & %d) != 0 || (mediaSubtype & %d) != 0",      PHAssetMediaSubtypePhotoPanorama,PHAssetMediaSubtypeVideoHightFrameRate];PHFetchResult *result = [PHAssetfetchAssetWithOptions:fetchOptions];

    NSArray *sortDescriptors

    用于指定获取的对象的顺序

    用一个例子实现以时间顺序倒序(刚拍摄的照片放在前头排列获取图片的功能:

    PHFetchOption *option= [PHFetchOption new];option.sourtDescriptors = @[NSSortDescriptors sortDescriptiorWithKey:@"creationDate"ascending:NO];PHFetchResult *result = [PHAsset fetchAssetsWithOptions:option];

    其他几个属性:

    //用于确定app是否接收到了具体的改变信息。@property(nonatomic, assign) BOOL wantsIncrementalChangeDetails/**

    *限制检索获取得到的photo实体的最小数量,当实体数量十分巨大时,作用显著,

    *例如,用'PHAsset'的'fetchAssetsWithOptions:'方法获取最近拍摄的照片等。

    */@property(nonatomic, assign, readwrite) NSUInteger fetchLimit//检索结果是否包含连拍图片,如果是NO,只显示用户选取的那种图片,如果为YES,@property(nonatomic, assign) BOOL includeAllBurstAssets//顾名思义,是否检索隐藏的图片@property(nonatomic, assign) BOOL includeHiddenAssets/**

    *包含的数据类型:

    *PHAssetSourceTypeUserLibrary

    *PHAssetSourceTypeCloudShared

    *PHAssetSourceTypeiTunesSynced

    */@property(nonatomic, assign) PHAssetSourceType includeAssetSourceTypes

    PHImageRequestOption

    PHImageRequestOption 用于配置从PHImageManager中获取asset的请求。

    常用的一些属性和方法有:

    /**

    *  @discuss 如果是NO,表示为异步操作,从manager中请求图片时,

    *  'reqeustImageForAssets:targetSize:options:resultHandler'方法会立即返回,

    *  建议在后台只在后台线程中执行同步请求

    */@property(nonatomic,assign)BOOLsynchronous;/**

    *typedef : NSInteger {

    PHImageRequestOptionsDeliveryModeOpportunistic = 0,

    PHImageRequestOptionsDeliveryModeHighQualityFormat = 1,

    PHImageRequestOptionsDeliveryModeFastFormat = 2,

    } PHImageRequestOptionsDeliveryMode;

    *@PHImageRequestOptionsDeliveryModeOpportunistic:

    自动返回一个或多个结果,来平衡图片的质量和响应性,它会多次调用

    resutltHandler:'requestImageForAssets:targetSize:options:resultHandler'.

    它首先会先调用一次'resutltHandler'返回清晰度低的图片作为临时显示图片,

    等到能获取到高清晰度的图片时再次调用'resutltHandler'返回高质量图片。

    note:如果'synchronous'是NO那么该属性无效

    *@PHImageRequestOptionsDeliveryModeHighQualityFormat

    只返回高分辨率的图片。具有较高的优先权

    *@PHImageRequestOptionsDeliveryModeFastFormat

    快速返回结果,可能会牺牲图片质量。

    */@property(nonatomic,assign) PHImageRequestOptionsDeliveryMode deliveryMode;/**

    *  a mode that specifies how to resize the reuqested image

    */@property(nonatomic,assign) PHImageRequestOptionsResizeMode resizeMode;

    从iCloud中下载照片

    /**

    *  能否从iCloud中下载图片,

    YES,本地也没有保存此图片,从iCloud上下载,用'progressHandler'这个block获取下载进度;

    NO,同时本地也没有图片,'progressHander'中的info[PHImageReustIsInCloudKey]返回值会表示不能下载

    */@property(nonatomic,assign,getter=isNetworkAccessAllowed)BOOLnetworkAccessAllowed;/**

    下载进度block,在多条线程中执行操作,刷新UI时需要回到主线程

    */typedefvoid(^ PHAssetImageProgressHandler)(doubleprogress,NSError*error,BOOL*stop,NSDictionary*info);@property(nonatomic,copy) PHAssetImageProgressHandler progressHandler

    PHFetchResult

    PHFetchRequest是有序的photo实体对象的容器,包含通过给定的检索条件返回的asset,相册,一个相册类型中的所有相册列表(例如,smart album类型下的所有相册,它是有序的),在PHAsset,PHCollection,PHAssetcollection,PHCollectionList这几个类中都包含有相应的类方法包含对应信息的PHFetchRequest对象,例如:

    PHAsset

    /***@param mediaType*aaset类型,包含有:*PHAssetMediaTypeUnknown = 0,*PHAssetMediaTypeImage,*PHAssetMediaTypeVideo,*PHAssetMediaTypeAudio,**@param options  检索操作**@return 带有符合条件的PHAsset对象集合的PHFetchRequest对象*/

    +(PHFetchResult*)fetchAssetsWithMeidaType:(PHAssetMediaType)mediaType

    options:(PHFetchOptions *)options

    PHCollection (抽象类,不允许直接使用,开发过程中用它的两个子类PHCollectionList和PHAssetCollection替代)

    //Retrieves collectionsfromthe rootofthe photo library’s hierarchyofuser-created albumsandfolders.+(PHFetchResult *)fetchTopLevelUserCollectionsWithOption:(PHFetchOptions *)options;

    PHAssetCollection:

    /***  获取自定条件的相册**  @paramtype相册类型:PHAssetCollectionTypeAlbumPHAssetCollectionTypeSmartAlbumPHAssetCollectionTypeMoment*  @param subtype相对于相册类型更具体些的相片类型,如全景,照片流等*  @param options 检索条件**  @return 符合条件的相册*/+(PHFetchResult *)fetchAssetColletcionsWithType:(PHAssetCollectionType)typesubtype:(PHAssetCollectionSubtype)subtype                                                          options:(PHFetchOptions*)options;

    PHCollectionList:

    +(PHFetchResult *)fetchCollectionListsWithType:(PHCollectionListType)collectionListType                                                          subtype:(PHCollectionListSubtype)subtype                                                          options:(PHFetchOptions*)options

    PHFetchRequest虽然包含了符合条件的photo实体的集合,与NSArray不同的是它会动态改变包含的内容,在处理大量的asset的时候效率更高些,实现的效果也好点

    常用属性与方法

    //是否包含给定的对象-(BOOL)containsObject:(ObjectType)anObject//包含的photo实体个数@property(readonly)NSUIntegercount//指定类型的asset数量-(NSUInteger)countOfAssetsWithMediaType:(PHAssetMediaType)mediaType

    PHImageManager

    PHImageManager有一个单例方法,同时也提供了用于获取全尺寸图片,图片缩略图等方法.

    获取图片:

    /**

    *  会多次调用'resultHandler',第一次调用,返回的图片清晰度较低,

    *  当高清晰度图片可以获取时,会再次调用,如果高质量的图片在缓存汇中,只调用一次'resultHandler'。

    *  这个方法默认是异步的,当从后台线程调用这个方法时,需要将options的'synchronous'设为YES.

    *

    *  @param asset        保存图片信息的asset

    *  @param targetSize    返回的图片尺寸

    *  @param contentMode  返回的图片显示模式

    *  @param options      image request option

    *  @param resultHandler 返回的内容

    *

    *  @return 请求标示,用于取消请求*/-(PHImageRequestID)requestImageForAsset:(PHAsset*)assettargetSize:(CGSize)targetSizecontentMode:(PHImageContentMode)contentModeoptions:(PHImageRequestOptions*)optionsresultHandler:(void(^)(UIImage *result, NSDictionary *info))resultHandler;/**

    *  请求全尺寸的图片,只执行一次'resultHandler',

    *  如果options的'version'被设置为'PHImageRequestOptionsVersionCurrent,'

    *  返回在这个asset上发生的任何编辑后的imageData,如果不是的话,返回最原始版本的图片

    *

    *  @param asset        保存图片信息的asset

    *  @param options      image request option

    *  @param resultHandler 返回的内容

    *

    *  @return 请求标示,用于取消请求

    */-(PHImageRequestID)requestImageDataForAsset:(PHAsset*)assetoptions:(PHImageRequestOptions*)optionsresultHandler:(void(^)(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info))resultHandler;

    取消请求:

    -(void)cancelImageRequest:(PHImageRequestID)requestID

    PHCachingImageManager

    PHCachingImageManager是PHImageManager的子类,如果相册中有大量的图片,而你的需求是要快速的获取这些图片的缩略图和大图数据用于展示,这个时候可以用PHCachingImageManager来实现,它具有缓存机制可以快速获取一个图册的缩略图,或者在后台请求全尺寸图片以便于快速展示。

    开始缓存图片:

    /** *@discuss当调用这个方法的时候,cacaingManager开始在获取你所需要的数据, *  同时在后台生成缩略图,之后可以使用'requestImagesFromAssets:targetSize:contentMode:resultHandler:' *  方法从缓存中请求数据。 *  Photos会按照给定的尺寸,显示模式返回图片,缓存中的图片尺寸是固定的 * *@paramassets      需要缓存的assets *@paramtargetSize  图片尺寸 *@paramcontentMode 显示模式 *@paramoptions    请求操作 */- (void)startCachingImagesForAssets:(NSArray *)assetstargetSize:(CGSize)targetSizecontentMode:(PHImageContentMode)contentModeoptions:(PHImageRequestOptions *)options;

    取消图片缓存:

    /** *  当使用collectionView展示图片缩略图的时候,如果需要改变尺寸大小的时候, *  就需要将缓存中的旧图片删除重新缓存。 * *@paramassets      需要缓存的assets *@paramtargetSize  图片尺寸 *@paramcontentMode 显示模式 *@paramoptions    请求操作 */- (void)stopCachingImagesForAssets:(NSArray *)assetstargetSize:(CGSize)targetSizecontentMode:(PHImageContentMode)contentModeoptions:(PHImageRequestOptions *)options;

    PHPhotoLibrary

    PHPhotoLibrary可以看成是一个用户图库,包含了一些的图片和相册,同时包含本地的和iCloud中的资源。当Photos app发生图片的修改、增加、删除等改变时,使用PHPhotoLibrary来做一些刷新UI,保存数据等响应动作,同时也可以注册观察者(使用registerChangeObserver方法),当Photos app内容发生改变的时,会触发代理方法photoLibraryDidChange。

    使用PHPhotoLibrary响应图库改变

    Photos中的PHAsset,PHAssetCollection等是不可变对象,因此要改变当前这些类型对象的时候就需要使用photo library实现改变。

    请求改变数据需要用到PHAssetChangeRequest,PHAssetcCollectionChangeRequest,PHCollectionListChangeRequest。

    使用步骤:

    1、创建实体

    每个change request类都提供了用于创建响应的实体类的方法:

    creationRequestForAssetCollectionWithTitle:创建了一个asset Collection

    如果要添加一个新的asset到collection中,需要用到change request提供的PHObjectPlaceholder对象。在change block结束之后,使用placeholder对象提供的localIdentifier属性获取创建好的asset对象。

    2、删除实体

    例如:deleCollectionLists用于删除collection list

    3、修改实体

    changeRqeustForAsset创建了一个可用于修改的asset的change request

    下面代码实现往相册中添加新图片的功能:

    - (void)addNewAssetWithImge:(UIImage*)image toAlbum:(PHAssetCollection *)album {    [[PHPhotoLibrarysharedPhotoLibrary]performChanges:^{        PHAssetChangeRequest *assetChange = [PHAssetChangeRequest creationRequestForAssetFromImage:image];PHAssetCollectionChangeRequest *collectionChange = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:album];PHObjectPlaceholder *placeholder = [assetChange placeholderForCreatedAsset];[collectionChangeaddAssets:@[placeholder]];} completionHandler:^(BOOLsuccess, NSError * _Nullable error) {      NSLog(@"Finished adding asset. %@", (success ? @"Success": error));}];}

    note:For each call to the performChanges:completionHandler: or performChangesAndWait:error: method, iOS shows an alert asking the user for permission to edit the contents of the photo library.

    注册观察者

    PHPhotoLibraryChangeObserver在系统图库发生变化的时候就会通知指定的观察者,只要是使用了Photos framework实现的改变,都会触发观察者的方法。

    registerChangeObserver:方法指定一名观察者,当系统图库发生改变,会触发观察者的指定方法,这个方法在PHPhotoLibraryChangeObserver协议中:- (void)photoLibraryDidChange:(PHChange *)changeInfo ;

    PHCollection

    PHCollection是一个抽象类,不允许直接使用它的实例对象,而是使用它的两个子类:PHAssetCollection,PHCollectionList:

    PHAssetCollection 包含了带有图片或者视频信息PHAsst对象,PHCollectionList可以看做是一个文件夹,里面存放多个相册或者是在年度相册中的所有时刻的照片。

    获取图片集合:

    //用特定的操作从collection list中获取collection集合+ (PHFetchResult)fetchCollectionsInCollectionList:(PHCollectionList *)collectionListoptions:(PHFetchOptions *)options//获取所有用户创建的相册或者文件夹。+ (PHFetchResult *)fetchTopLevelUserCollectionWithOptions:(PHFetchOptions *)options;

    PHAssetCollection

    一个PHAssetCollection代表一个相册,可能包含图片和视频,例如:时间相册,我的照片流,自拍。

    在Photos framework中不能直接获取collection中的内容,通过fetchAssetsInAssetCollecton:options:获取到包含PHAsset集合的PHFecthReult对象,之后用fetchResult提供的方法取出图片或者视频。

    获取asset collection 的方法有许多种:

    /** *  @paramtype相册类型:PHAssetCollectionSubtypeAlbumRegularPhotosAPP中创建的相册PHAssetCollectionSubtypeAlbumSyncedEvent从iPhoto中同步的事件相册PHAssetCollectionSubtypeAlbumSyncedFaces从iPhoto中同步的包含人脸的相册PHAssetCollectionSubtypeAlbumSyncedAlbum从iPhoto同步的普通相册PHAssetCollectionSubtypeAlbumImported从其他设备导入的相册PHAssetCollectionSubtypeAlbumCloudShared分享到iCloud的照片流相册PHAssetCollectionSubtypeAlbumMyPhotoStream用户个人的iCloud照片流PHAssetCollectionSubtypeSmartAlbumGeneric没有特定类型的只能相册PHAssetCollectionSubtypeSmartAlbumPanoramas全景图片相册PHAssetCollectionSubtypeSmartAlbumVideos视频相册PHAssetCollectionSubtypeSmartAlbumFavorites个人收藏PHAssetCollectionSubtypeSmartAlbumTimelapses延时摄影相册PHAssetCollectionSubtypeSmartAlbumAllHidden隐藏的图片相册PHAssetCollectionSubtypeSmartAlbumRecentlyAdded最近添加的图片PHAssetCollectionSubtypeSmartAlbumBursts连拍相册PHAssetCollectionSubtypeSmartAlbumSlomoVideos慢动作视频相册PHAssetCollectionSubtypeSmartAlbumUserLibrary在本地存在的相册(不包含icloud中的相册)PHAssetCollectionSubtypeSmartAlbumSelfPortraits自拍PHAssetCollectionSubtypeSmartAlbumScreenshots截屏PHAssetCollectionSubtypeAny获取所有类型的相册 *  @param options 筛选操作 * *  @return 包含符合条件的相册的fetch result */+ (PHFetchResult *)fetchAssetCollectionsWithType:(PHAssetCollectionType)typesubtype:(PHAssetCollectionSubtype)subtype options:(nullablePHFetchOptions*)options;/** *  获取符合特定类型同时包含指定asset的相册集合 * *  @param asset  给定的sset *  @paramtype指定相册类型 *  @param options 获取操作 * */+ (PHFetchResult *)fetchAssetCollectionsContainingAsset:(PHAsset*)asset withType:(PHAssetCollectionType)typeoptions:(PHFetchOptions*)options;

    PHCollectionList

    PHCollectionList包含了更高级别的asset集合,可嵌套PHAssetCollection

    和自身类型,还支持多重嵌套,例如获取时刻相册和时刻相册中年度照片等。

    获取collection list的几种方法:

    + (PHFetchResult)fetchCollectionListsContainingCollection:(PHCollection*)collection options:(PHFetchOptions*)options;+ (PHFetchResult *)fetchCollectionListsContainingCollection:(PHCollection*)collection options:(nullablePHFetchOptions*)options;+ (PHFetchResult *)fetchCollectionListsWithLocalIdentifiers:(NSArray *)identifiers options:(nullablePHFetchOptions*)options;+ (PHFetchResult *)fetchCollectionListsWithType:(PHCollectionListType)collectionListType subtype:(PHCollectionListSubtype)subtype options:(nullablePHFetchOptions*)options;+ (PHFetchResult *)fetchMomentListsWithSubtype:(PHCollectionListSubtype)momentListSubtype containingMoment:(PHAssetCollection*)moment options:(nullablePHFetchOptions*)options;+ (PHFetchResult *)fetchMomentListsWithSubtype:(PHCollectionListSubtype)momentListSubtype options:(nullablePHFetchOptions*)options;

    PHAsset

    PHAsset代表一个视频或者图片资源,当需要展示或者修改Photos app中的图片时需要先获取asset,asset是不可改变的并且只保存了所代表的视频或者图片的metadata。

    获取PHAsset的几种方法:

    //从asset collection中获取符合条件的asset集合+ (PHFetchResult *)fetchAssetsInAssetCollection:(PHAssetCollection *)assetCollectionoptions:(PHFetchOptions *)options/**

    *  默认返回所有类型的asset,如果要给asset添加更多的类型限定,可以在options的filter predicate中设置。

    *  @param mediaType :

    PHAssetMediaTypeUnknown

    未知类型

    PHAssetMediaTypeImage

    静态图片

    PHAssetMediaTypeVideo

    视频

    PHAssetMediaTypeAudio

    音频

    注: PHMediaSubtype:

    PHAssetMediaSubtypeNone              = 0,

    // Photo subtypes

    PHAssetMediaSubtypePhotoPanorama      = (1UL << 0),

    PHAssetMediaSubtypePhotoHDR          = (1UL << 1),

    PHAssetMediaSubtypePhotoScreenshot NS_AVAILABLE_IOS(9_0) = (1UL << 2),

    PHAssetMediaSubtypePhotoLive NS_AVAILABLE_IOS(9_1) = (1UL << 3),

    // Video subtypes

    PHAssetMediaSubtypeVideoStreamed      = (1UL << 16),

    PHAssetMediaSubtypeVideoHighFrameRate = (1UL << 17),

    PHAssetMediaSubtypeVideoTimelapse    = (1UL << 18),

    */+ (PHFetchResult   *_Nullable)fetchAssetsWithMediaType:(PHAssetMediaType)mediaTypeoptions:(PHFetchOptions *_Nullable)options;+ (PHFetchResult * *)fetchAssetsWithLocalIndentifiers:(NSArray )identifieroptions:(PHFetchOptions *)options;/**

    *  获取key asset,每一个collection都至少有一个key asset,每个不同类型的collection用于定义key asset的方式也不同,有的collection中只有一个key asset,有的含有多个。

    *  例如在相机胶卷中,最近拍摄的图片或者视频就是key asset

    */+ (PHFetchResult )fetchKeyAssetsInAssetCollection:(PHAssetCollection *)collectionoptions:(PHFetchOptions *)options;/**

    *  获取所有的符合条件的asset,默认条件下,不包含通过iTunes同步过来的和存储在iCloud中的图片。

    *  更改此条件,配置options的'includeAssetSourceType'属性来实现。

    */+ (PHFetchResult *)fetchAssetsWithOptions:(PHFetchOptions *)options;//获取连拍照片+ (PHFetchResult )fetchAssetWithBurstIdentifier(NSString *)burstIdentifieroptions:(PHFetchOptions *)options;

    相关文章

      网友评论

        本文标题:Photos中常用类(获取展示功能相关)简介

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