使用PHAsset检索多个图像

时间:2016-01-21 19:36:21

标签: ios swift phasset

我尝试使用PHAsset从用户的相机胶卷中检索超过1,000张图像,但如果它只是缩略图,则会导致崩溃或花费很长时间。这是我的功能,我检索图像......

func retrieveImages(thumbnail: Bool) {

    /* Retrieve the items in order of modification date, ascending */
    let options = PHFetchOptions()
    options.sortDescriptors = [NSSortDescriptor(key: "modificationDate",
        ascending: false)]

    /* Then get an object of type PHFetchResult that will contain
    all our image assets */
    let assetResults = PHAsset.fetchAssetsWithMediaType(.Image,
        options: options)

    let imageManager = PHCachingImageManager()

    assetResults.enumerateObjectsUsingBlock{(object: AnyObject!,
        count: Int,
        stop: UnsafeMutablePointer<ObjCBool>) in


        if object is PHAsset{
            let asset = object as! PHAsset
            print("Inside  If object is PHAsset, This is number 1")

            var imageSize: CGSize!

            if thumbnail == true {
                imageSize = CGSize(width: 100, height: 100)

            } else {
                imageSize = CGSize(width: self.cameraView.bounds.width, height: self.cameraView.bounds.height)

            }
            /* For faster performance, and maybe degraded image */
            let options = PHImageRequestOptions()
            options.deliveryMode = .FastFormat
            options.synchronous = true

            imageManager.requestImageForAsset(asset,
                targetSize: imageSize,
                contentMode: .AspectFill,
                options: options,
                resultHandler: { (image, _: [NSObject : AnyObject]?) -> Void in
                    if thumbnail == true {
                        self.libraryImageThumbnails.append(image!)
                        self.collectionTable.reloadData()
                    } else {
                        self.libraryImages.append(image!)
                        self.collectionTable.reloadData()

                    }
            })

            /* The image is now available to us */

            print("enum for image, This is number 2")



            print("Inside  If object is PHAsset, This is number 3")
        }
        print("Outside If object is PHAsset, This is number 4")

    }



}

如果需要更多信息,请告诉我。谢谢!

2 个答案:

答案 0 :(得分:1)

通常,您 希望加载大量的全尺寸或屏幕尺寸的图像并自行保存在内存中。对于那个尺寸,你一次只能呈现一个(或两个或三个,如果你想预先加载屏幕转换动画),所以你不需要获取超过一次。

同样,加载数百或数千个缩略图并自行缓存它们会导致内存问题。 (将您的集合视图反复告诉reloadData会导致大量的流失。)相反,让Photos框架管理它们 - 它具有确保仅在需要时生成缩略图并在使用之间缓存的功能,甚至可以帮助您完成任务,例如在用户在集合视图中滚动时只抓取您需要的缩略图。

Apple的Using Photos Framework示例代码项目显示了几种获取图像的最佳做法。以下是一些主要观点的摘要:

  1. AssetGridViewController管理缩略图的集合视图,缓存初始化时给予它的PHFetchResult<PHAsset>。有关获取结果的信息(如计数)是集合视图基本管理所需的全部内容。

  2. AssetGridViewController仅在集合视图要求显示单元格时,单独请求来自PHImageManager的缩略图图像。这意味着我们只知道要看到一个单元格时才创建UIImage,并且我们不必告诉集合视图一遍又一遍地重新加载所有内容。

  3. 就其本身而言,第2步将导致慢滚动,或者更确切地说,在滚动后减慢加载到单元格中的图像的追赶。所以,我们也这样做:

    1. 我们不使用PHImageManager.default(),而是保留PHCachingImageManager的实例,并告诉它我们想要的图像集是什么?预热&#34;用户滚动时的缓存。

      AssetGridViewController有一些额外的逻辑用于跟踪滚动视图的可见矩形,以便图像管理器知道为当前可见的项目准备缩略图(加上一点滚动向前),并且可以如果需要,项目的免费资源将不再可见。请注意,预取不会创建UIImage,只需从磁盘启动必要的加载或从iCloud下载,因此您的内存使用率会保持很小。

    2. 在集合视图中选择项目时(要转到该照片的全屏演示文稿),AssetViewController使用默认PHImageManager请求屏幕大小(不完整) - 大小)图像。

      机会投放意味着我们会立即获得质量较低的版本(基本上与我们之前在集合视图中使用的照片相同的缩略图),以及不久之后的更高质量版本(异步,之后我们自动更新视图。

      如果您需要支持缩放(示例代码应用程序不支持,但它可能是真正的应用程序),您可以在完成后立即请求全尺寸图像 - 屏幕视图(以花费较长时间从放大缩略图转换为全屏图像为代价),或者通过请求屏幕大小的图像开始,然后还请求完整尺寸的图像以供以后传送。

      < / LI>

答案 1 :(得分:0)

在CellForRowAtIndexPath中使用PHImageManager的RequestImageForAsset方法来延迟加载UIImageView上的image属性。