iOS开发之AssetsLibrary与photokit总结

demo下载地址在最下方

一、AssetsLibrary

iOS提供的AssetsLibrary是用来读取和操作本地相册的,相当于app与系统相册之间的桥梁,该框架提供了以下的几个类:ALAssetsLibrary,ALAssetsGroup,ALAsset,ALAssetsFilter,ALAssetRepresentation

ALAssetsLibrary:本地资源库对象

ALAssetsGroup:本地相册分组对象,本地有多少个相薄就会有几个ALAssetsGroup类型的对象。

ALAsset:从本地相册获取的图片或者视频的对象都是ALAsset类型的对象。

ALAssetsFilter:对本地所有资源的过滤筛选,可以选择只获取照片,只获取视频,或者获取所有的资源。

ALAssetRepresentation:获取视频或者图片的url,文件名,二进制数据,封面缩略图等。

在这里先介绍一些比较常用的方法:

ALAssetsLibrary

1、获得相册的组别

- (void)enumerateGroupsWithTypes:(ALAssetsGroupType)types usingBlock:(ALAssetsLibraryGroupsEnumerationResultsBlock)enumerationBlock failureBlock:(ALAssetsLibraryAccessFailureBlock)failureBlock

在这个方法可以获取分组的列表,包括名称、封面图片等,其中有以下几个type:ALAssetsGroupLibrary,ALAssetsGroupAlbum,ALAssetsGroupEvent,ALAssetsGroupFaces,ALAssetsGroupSavedPhotos,ALAssetsGroupPhotoStream,ALAssetsGroupAll。

2、返回一个ALAsset对象

- (void)assetForURL:(NSURL *)assetURL resultBlock:(ALAssetsLibraryAssetForURLResultBlock)resultBlock failureBlock:(ALAssetsLibraryAccessFailureBlock)failureBlock

3、返回一个ALAssetsGroup对象

- (void)groupForURL:(NSURL *)groupURL resultBlock:(ALAssetsLibraryGroupResultBlock)resultBlock failureBlock:(ALAssetsLibraryAccessFailureBlock)failureBlock

ALAssetsGroup

ALAssetsGroup是获取相册组的类,可以通过这个类提供的方法来获取相册组的信息

1、获得名称、类型、ID、NSURL

- (id)valueForProperty:(NSString *)property;

property可以是:

ALAssetsGroupPropertyName:名称

ALAssetsGroupPropertyType:类型

ALAssetsGroupPropertyPersistentID:ID

ALAssetsGroupPropertyURL :NSURL

2、获得相册分组的封面图片

- (CGImageRef)posterImage;

3、过滤器

- (void)setAssetsFilter:(ALAssetsFilter *)filter

ALAssetsFilter一下这些方法是过滤类型:

+ (ALAssetsFilter *)allPhotos;

+ (ALAssetsFilter *)allVideos;

+ (ALAssetsFilter *)allAssets;

4、获得相册的组的数量

- (NSInteger)numberOfAssets;

5. 通过相册组获取里面的图片

- (void)enumerateAssetsUsingBlock:(ALAssetsGroupEnumerationResultsBlock)enumerationBlock 

- (void)enumerateAssetsWithOptions:(NSEnumerationOptions)options usingBlock:(ALAssetsGroupEnumerationResultsBlock)enumerationBlock 

- (void)enumerateAssetsAtIndexes:(NSIndexSet *)indexSet options:(NSEnumerationOptions)options usingBlock:(ALAssetsGroupEnumerationResultsBlock)enumerationBlock

ALAssetRepresentation

ALAssetRepresentation对象封装了一个给定对象ALAsset对象的描述

具体参考:

blog.csdn.net/meegomeego/article/details/21165145

ALAsset

- (id)valueForProperty:(NSString *)property;

有以下几个类型:

ALAssetPropertyType 资源的类型(照片,视频)

ALAssetPropertyLocation 资源地理位置(无位置信息返回null)

ALAssetPropertyDuation 播放时长(照片返回ALErorInvalidProperty)

ALAssetPropertyOrientation 方向(共有8个方向,参见:ALAssetOrientation)

ALAssetPropertyDate 拍摄时间(包含了年与日时分秒)

ALAssetPropertyRepresentations 描述(打印看了下,只有带后缀的名称)

ALAssetPropertyURLs(返回一个字典,键值分别是文件名和文件的url)

ALAssetPropertyAssetURL 文件的url

//得到缩略图

- (CGImageRef)thumbnail;

以上是对AssetsLibrary的总结,下面是对photokit框架的总结

二、photokit

photokit是iOS8出的一个新的图片选择框架,用来取代上述AssetsLibrary框架,相比较AssetsLibrary来说photokit更加灵活,而在iOS9中,AssetsLibrary已经被弃用,也不支持livephoto,并且使用AssetsLibrary时,图片的分辨率会变低,接下来就介绍一下photokit。

Photos中有以下几个类:

PHAdjustmentData:当用户编辑资源,照片与修改后的图像或视频数据保存在一个PHAdjustmentData对象中

PHAsset:代表照片库中的一个资源实体,可以理解为一张照片,在打印的时候,可以清楚的看见里面包含了照片的时间、标题等信息

PHAssetChangeRequest:使用PHAssetChangeRequest对象来创建、删除和修改相片库里面的PHAsset对象

PHAssetCollectionChangeRequest:使用PHAssetCollectionChangeRequest对象来创建、删除和修改相片库里面的PHAssetCollection对象

PHAssetCreationRequest:使用PHAssetCreationRequest对象构造一个新的照片或视频,并将其添加到照片库

PHAssetResource:一个PHAssetResource对象表示在照片库中的照片或视频资源(也就是一个PHAsset对象)相关联的基础数据资源之一,使用PHAssetResourceManager类获取它

PHAssetResourceManager:PHAssetResourceManager对象提供了访问与照片资源相关的资源基础数据存储方法

PHChange:PHChange对象来通知的照片库中的资源的一些变法,比如增加和删除

PHCollection:PHAssetCollection对象表示一组照片或视频资源。包括时刻和相册中可见照片应用,以及特殊的集合,如共享照片流。

PHCollectionListChangeRequest:使用PHCollectionListChangeRequest对象在一个照片库中创建、删除或修改PHCollectionList对象。

PHContentEditingInput:PHContentEditingInput对象描述资产用于编辑元数据

PHContentEditingOutput:PHContentEditingOutput对象表示编辑照片资产的照片或视频内容的结果

PHFetchOptions:获取资源时的检索参数,可以传 nil,即使用系统默认值

PHFetchResult:通过PHFetchResult来获取照片实体的有序列表

PHImageManager:PHImageManager对象提供用于加载与PHAsset对象相关联的图像或视频数据的方法。使用这些方法来获取全尺寸照片资产或缩略图,或者检索AV Foundation对象播放,导出和操纵的视频资产。

PHLivePhoto:用来获取LivePhoto实体

PHObject:照片等实体的抽象类

PHPhotoLibrary:PHPhotoLibrary对象表示用户的照片库整套资源和收藏的照片,包括存储在本地设备上在iCloud的照片对象。

PhotosTypes:与Photos框架相关的类型的枚举

使用photokit最直观明了的地方就是一下这个关系:

PHCollectionList,它表示一组 PHCollection,它本身也是一个 PHCollection,因此 PHCollection 作为一个集合,可以包含其他集合,这使得 PhotoKit 的组成比 ALAssetLibrary 要复杂一些。另外与 ALAssetLibrary 相似,一个 PHAsset 可以同时属于多个不同的 PHAssetCollection,最常见的例子就是刚刚拍摄的照片,至少同时属于“最近添加”、“相机胶卷”以及“照片 - 精选”这三个 PHAssetCollection,他们的关系如下图:


photokit的机制:

采用“获取”的方式拉取资源,从 PHAssetCollection 中获取到的可以是相册也可以是资源,但无论是哪种内容,都统一使用 PHFetchResult 对象封装起来,因此虽然 PHAssetCollection 获取到的结果可能是多样的,但通过 PHFetchResult 就可以使用统一的方法去处理这些内容(即遍历 PHFetchResult)

// 列出所有相册智能相册

PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];

// 这时 smartAlbums 中保存的应该是各个智能相册对应的 PHAssetCollection

for (NSInteger i = 0; i < fetchResult.count; i++) {

// 获取一个相册(PHAssetCollection)

PHCollection *collection = fetchResult[i];

if ([collection isKindOfClass:[PHAssetCollection class]]) {

PHAssetCollection *assetCollection = (PHAssetCollection *)collection;

// 从一个相册中获取的PHFetchResult中包含的才是PHAsset

PHFetchResult *fetchResult = [PHAsset fetchAssetsInAssetCollection:assetCollection options:fetchOptions];

else {

NSAssert(NO, @"Fetch collection not PHCollection: %@", collection);

}

// 获取所有资源的集合,并按资源的创建时间排序

PHFetchOptions *options = [[PHFetchOptions alloc] init];

options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];

PHFetchResult *assetsFetchResults = [PHAsset fetchAssetsWithOptions:options];

// 这时 assetsFetchResults 中包含的,应该就是各个资源(PHAsset)

for (NSInteger i = 0; i < fetchResult.count; i++) {

// 获取一个资源(PHAsset)

PHAsset *asset = fetchResult[i];

}

到了这里已经成功取出了PHAsset,接下来做的操作就是获取图片

可以首先进行一下设置

PHImageRequestOptions *reques = [[PHImageRequestOptions alloc]init];

reques.synchronous = NO;//获取图片方式是否开启异步

reques.resizeMode = PHImageRequestOptionsResizeModeFast;

reques.deliveryMode = PHImageRequestOptionsDeliveryModeFastFormat;

此时可以进行图片获取了:

- (PHImageRequestID)requestImageForAsset:(PHAsset *)asset

targetSize:(CGSize)targetSize

contentMode:(PHImageContentMode)contentMode

options:(nullable PHImageRequestOptions *)options

resultHandler:(void (^)(UIImage *__nullable result, NSDictionary *__nullable info))resultHandler;

resizeMode对应以下三个属性:

1、PHImageRequestOptionsResizeModeNone,

2、PHImageRequestOptionsResizeModeFast, //根据传入的size,迅速加载大小相匹配(略大于或略小于)的图像

3、PHImageRequestOptionsResizeModeExact //精确的加载与传入size相匹配的图像

PHImageRequestOptionsDeliveryMode

PHImageRequestOptionsDeliveryMode是一个enum类型的,它囊括了非常复杂的操作,有三个值分别对应:

PHImageRequestOptionsDeliveryModeOpportunistic 当选用此项时,Photos会在你请求时给你提供一个或者多个结果,这就意味着resultHandler block可能会执行一次或多次,例如

Photos会先给你一个低分辨率的图片让你暂时显示,然后加载出高质量的图片后再次给你。如果PHImageManager已经pre-cache了图片,那result handler便只会执行一次。另外,如果synchronous属性为NO,此选项是不起作用的。

PHImageRequestOptionsDeliveryModeHighQualityFormat 当请求image时 不管请求需要多长时间完成,Photos只会提供高质量的image。另外,当synhronous属性为YES 或者使用requestImageDataForAsset:options:resultHandler: 方法时,这个选项是默认且唯一的。

PHImageRequestOptionsDeliveryModeFastFormat 当请求image时,高质量的图片或低质量的图片,谁加载的快 便显示谁。另外Photos也能通过检查info字典(resultHandler中的参数)里的PHImageResultIsDegradedKey值来判定传高质量或者低质量的图片。

targetSize

需要获取的图像的尺寸,如果输入的尺寸大于资源原图的尺寸,只返回原图

contentMode

图像的裁剪方式,与UIView的contentMode参数相似,控制图片是按比例缩放还是按比例填充的方式放在展示的控件中,但如果传入的targetSize是PHImageManagerMaximumSize,contentMode不管传什么值都是PHImageContentModeDefault;

这样整个调取图片的过程就已介绍完毕,最后可以得到一个包含资源对于图像的UIImage和一个包含图像信息的NSDictionary,而在整个过程中,这个block会被多次调用,通俗来说就是在开始的时候给你放一张低质量的图上去,等它拿完之后给你呈现出高清图,具体的效果可以查看微信聊天发图片时大图预览,滑动时会先出现一张模糊的图片,然后马上呈现高清图片。


以上就是我对AssetsLibrary以及photokit的大致总结,这段时间通过在项目中进行实际的使用操作后发现了两者之间的区别:

首先就是二者的机制:

1、在 ALAssetLibrary 中获取数据,无论是相册,还是资源,本质上都是使用枚举的方式,遍历照片库取得相应的数据,并且数据是从 ALAssetLibrary(照片库) - ALAssetGroup(相册)- ALAsset(资源)这一路径逐层获取,即使有直接从 ALAssetLibrary 这一层获取 ALAsset 的接口,本质上也是枚举 ALAssetLibrary 所得,并不是直接获取,这样的好处很明显,就是非常符合实际应用中资源的显示路径:照片库 - 相册 - 图片或视频,但由于采用枚举的方式获取资源,效率低而且不灵活。而在 PhotoKit 中,则是采用“获取”的方式拉取资源,通过上文的机制可以得知。

2、由于二者的机制以及层次关系问题,二者获取到的资源也不一样,所以iOS会在iOS9中开始废弃ALAssetLibrary而采用photokit。ALAssetLibrary中获取所有相册资源使用的ALAssetsGroupAll属性,而到了iOS9之后,对于个人收藏等一张图片可以同时存在于多个相簿的资源来说,就会取不到这些公用相簿,而photokit的PHCollectionList的关系就可以取到这些资源,从而可以方便并且高效的达到我们需要的效果。

3、从获取资源的方式来看,photokit比ALAssetLibrary更加高效并且更加灵活。

以上是我最近实践发现的一些两者的区别。如果还有其他的,希望大家可以在评论区留言给我我会再更新补充。接下来是我最近项目使用photokit框架所遇到的问题,希望有遇到该问题的朋友能够和我一起探讨,如果能有解决办法,也希望可以给予我一些帮助。

在最新的photokit框架中上文已经提到获取图片的block会调用多次,而在我们进行项目测试时,发现在1000张图片之内,本身是很快并且很高效的。

这里贴上demo地址https://github.com/Archerry/WMHAlbumSelectOC.git(之前会崩溃的已经替换掉了,现在换上最近重构优化的)

上面是OC版本,这个是swift版本github.com/Archerry/swift-photokit

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容