iOS开发进阶 - 基于PhotoKit的图片选择器

原创 2017年01月11日 15:21:34

移动端访问不佳,请访问我的个人博客

很早之前就用OC把代码写完了并用在项目中了,一直没时间整理,现在用swift重写一份,并且更加详细的来了解这个Photos框架,下面是我集合苹果官方文档和其他大神的博客写出的一篇关于Photos框架的介绍

老规矩先上效果图和Demo地址

wcl

了解Photos框架

Photos是ios8出的一个新的图片选择框架,取代之前的AssetsLibrary框架,相比较AssetsLibrary框架Photos的用法更加灵活,发现在iOS9中AssetsLibrary已经被弃用了,并且也不支持livePhoto,iOS9上再使用AssetsLibrary框架时还有个严重的问题就是图片分辨率会变的很低,这篇文章主要讲解一下Photos的简单用法,用它做一个简单的图片选择器。

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框架相关的类型的枚举

获取相册列表

获取相册列表可以需要用到一下类:

  • PHFetchOptions:对象检索的对象,可以对相册列表进行筛选
  • PHAssetCollection:图片集合的对象,筛选后获得的集合

下面是获取相册列表的代码片段:

    //MARK: 属性列表
    //全部相册的数组
    private(set) var photoAlbums    = [[String: PHFetchResult<PHAsset>]]()
    private(set) var selectPhotoArr = [PHAsset]()

    //是否同步请求图片
    public var isSynchronous: Bool = false {
        didSet{
            self.photoOption.isSynchronous = isSynchronous
        }
    }

    //MARK: 初始化方法
    override init() {
        super.init()
        //图片请求设置成快速获取
        self.photoOption.resizeMode   = .fast
        self.photoOption.deliveryMode = .opportunistic
        getPhotoAlbum()
    }

    /**
     开始获取获取相册列表
     */
    private func getPhotoAlbum() {
        //创建一个PHFetchOptions对象检索照片
        let options = PHFetchOptions()
        //通过创建时间来检索
        options.sortDescriptors = [NSSortDescriptor.init(key: photoCreationDate, ascending: false)]
        //通过数据类型来检索,这里为只检索照片
        options.predicate = NSPredicate.init(format: "mediaType in %@", [PHAssetMediaType.image.rawValue])
        //通过检索条件检索出符合检索条件的所有数据,也就是所有的照片
        let allResult = PHAsset.fetchAssets(with: options)
        //获取用户创建的相册
        let userResult = PHAssetCollection.fetchTopLevelUserCollections(with: nil)
        //获取智能相册
        let smartResult = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .albumRegular, options: nil)
        //将获取的相册加入到相册的数组中
        photoAlbums.append([WCLImagePickerBundle.localizedString(key: "全部照片"): allResult])

        userResult.enumerateObjects(options: .concurrent) { (collection, index, stop) in
            let assetcollection = collection as! PHAssetCollection
            //通过检索条件从assetcollection中检索出结果
            let assetResult = PHAsset.fetchAssets(in: assetcollection, options: options)
            if assetResult.count != 0 {
                self.photoAlbums.append([assetcollection.localizedTitle!:assetResult])
            }
        }

        smartResult.enumerateObjects(options: .concurrent) { (collection, index, stop) in
            //通过检索条件从assetcollection中检索出结果
            let assetResult = PHAsset.fetchAssets(in: collection, options: options)
            if assetResult.count != 0 {
                self.photoAlbums.append([collection.localizedTitle!:assetResult])
            }
        }
    }

获取某个相册的所有图片列表

需要用到的类:

  • PHFetchResult:对象检索的对象,可以对图片进行筛选
  • PHAsset:图片资源的对象,代表一个图片或者视频资源

下面贴代码片段:

    /**
     通过下标返回相册的PHFetchResult

     - parameter index: 选择相册的index

     - returns: 相册的PHFetchResult
     */
    public func getAblumResult(_ ablumIndex: Int) -> PHFetchResult<PHAsset>? {
        if let ablum = self.photoAlbums[wcl_safe: ablumIndex] {
            if let result = ablum.values.first {
                return result
            }
        }
        return nil
    }

上面代码中返回的result就代表选中的相册的图片列表

获取到单张图片的数据

通过上面获取到的相册的图片列表通过下标就能获得到图片对应的PHAsset,需要用到的类:

  • PHCachingImageManager:获取图片数据的Manager,也可缓存数据
  • PHImageRequestOptions:获取图片的一些选项配置,比如获取方式等等
  • PHAsset:图片资源的对象,代表一个图片或者视频资源

下面是代码片段:

    /**
     根据PHAsset获取photo

     - parameter ablumIndex:    相册的index
     - parameter alasset:       相册里图片的PHAsset
     - parameter photoSize:     图片的size
     - parameter resultHandler: 返回照片的回调
     */
    public func getPhoto(_ photoSize: CGSize, alasset: PHAsset?, resultHandler: ((UIImage?, [AnyHashable: Any]?) -> Void)?) {
        if alasset != nil {
            let scale = UIScreen.main.scale
            let photoScaleSize = CGSize(width: photoSize.width*scale, height: photoSize.height*scale)
            self.photoManage.requestImage(for: alasset!, targetSize: photoScaleSize, contentMode: .aspectFill, options: self.photoOption, resultHandler: { (image, infoDic) in
                if image != nil {
                    resultHandler?(image, infoDic)
                }else {
                //没获取到返回默认图片
                    let image_buffer = WCLImagePickerBundle.imageFromBundle("image-buffer")
                    resultHandler?(image_buffer, infoDic)
                }
            })
        }
    }

将图片存入相册

有时候我们需要将应用里的图片存到相册里面,一下是会用到的类:

  • PHPhotoLibrary:代表我们手机中的图片库,用它来操作图片库中的图片
  • PHAssetChangeRequest:资源操作的请求类,用来对资源进行操作

代码片段:

//执行变化
PHPhotoLibrary.shared().performChanges({
        //创建一个图片资源
        PHAssetChangeRequest.creationRequestForAsset(from: image)
    }, completionHandler: { (flag, error) in
        //执行结果回调
    })

总结

以上简单的讲解了一下Photos相关知识点和使用方法,更多的可以去官方文档上去查看。用Photos自己写了一个图片选择器,大家有兴趣的可以去看一下,有用的话可以star一下,写不不是很好,有什么错误可以指出来~最后谢谢大家的阅读。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wang631106979/article/details/54343860

iOS开发之好用的图片选择第三方TZImagePickerController

最近的项目中涉及到了类似于发布朋友圈的功能,其中就需要上传照片等媒体内容,所以为了方便和效果好看,使用了TZImagePickerController第三方来管理和调用媒体内容,现在就是简单介绍一下这...
  • hbblzjy
  • hbblzjy
  • 2017-05-09 15:15:14
  • 10803

iOS 自定义多张图片选择+demo

if ([phoneVersion integerValue] >= 8) {         //高版本使用PhotoKit框架         [self getHeightVersionA...
  • wangxinxu521
  • wangxinxu521
  • 2017-06-05 15:39:00
  • 2767

iOS开发 图片选择器、图片多选功能的实现

iOS开发 图片选择器、图片多选功能的实现
  • dcw050505
  • dcw050505
  • 2016-10-24 23:23:56
  • 3772

iOS个人整理15-UIImagePickerController,照片选择器

一、UIImagePickerController UIImagePickerController是系统提供的用来获取图片和视频的接口 获取的途径为相机,图库,相册 分为以下几个步骤: 1. 初始化U...
  • u010330109
  • u010330109
  • 2016-01-30 09:01:24
  • 3359

UIImagePickerController 图像选取器--在iPhone中调用照相机、照片库—IOS开发

声明 欢迎转载,但是请尊重作者劳动成果,转载请保留此框内声明,谢谢。 文章出处:http://blog.csdn.net/iukey UIImagePickerControlle...
  • iukey
  • iukey
  • 2012-03-06 22:01:15
  • 14017

iOS PhotoKit 教程

Demo,简单实现了照片选择器的功能PhotoKitDemo 欢迎给Star!!! PHAsset: 代表照片库中的一个资源,跟 ALAsset 类似,通过 PHAsset 可以获取和保存资源 PH...
  • Xiejunyi12
  • Xiejunyi12
  • 2017-02-03 16:36:49
  • 373

ios PhotoKit遍历所有照片

//直接获取相机胶卷中的所有图片 - (void)getImagesFromCameraRoll { PHFetchOptions *options = [[PHFetchOptions al...
  • gl5773477
  • gl5773477
  • 2016-10-27 11:29:54
  • 1370

iOS PhotoKit框架 详解

一. 概况 本文侧重介绍在前文中简单介绍过的 PhotoKit 及其与 ALAssetLibrary 的差异,以及如何基于 PhotoKit 与 AlAssetLibrary 封装出通用的方法。 ...
  • QiuHaoZhou
  • QiuHaoZhou
  • 2016-06-01 15:37:28
  • 4430

iOS--PhotoKit简单入门

PhotoKit简介PhotoKit是一套比AssetsLibrary更为完整也更高效的库,对资源的处理与AssetsLibrary也有很大的不同。 首先介绍下几个概念: 1. PHAsset: 代...
  • C_Lluckying
  • C_Lluckying
  • 2016-07-16 17:20:12
  • 1117

IOS8 PhotoKit 范例

  • 2014年06月06日 14:00
  • 215KB
  • 下载
收藏助手
不良信息举报
您举报文章:iOS开发进阶 - 基于PhotoKit的图片选择器
举报原因:
原因补充:

(最多只允许输入30个字)