3

我有一个应用程序,可以让人们组合最多 4 张图片。但是,当我让他们从他们的照片中选择(最多 4 张)时,即使我将图像质量设置为 FastFormat,它也可能会非常慢。这将需要 4 秒(每张照片约 1 秒)。在最高质量下,4 张图像需要 6 秒。

无论如何,您能建议我更快地获取图像吗?

这是我处理图像的块。

func processImages()
    {
        _selectediImages = Array()
        _cacheImageComplete = 0
        for asset in _selectedAssets
        {
            var options:PHImageRequestOptions = PHImageRequestOptions()
            options.synchronous = true
            options.deliveryMode = PHImageRequestOptionsDeliveryMode.FastFormat
            PHImageManager.defaultManager().requestImageForAsset(asset, targetSize:CGSizeMake(CGFloat(asset.pixelWidth), CGFloat(asset.pixelHeight)), contentMode: .AspectFit, options: options)
                {
                    result, info in
                    var minRatio:CGFloat = 1
                    //Reduce file size so take 1/3 the screen w&h
                    if(CGFloat(asset.pixelWidth) > UIScreen.mainScreen().bounds.width/2 || CGFloat(asset.pixelHeight) > UIScreen.mainScreen().bounds.height/2)
                    {
                        minRatio = min((UIScreen.mainScreen().bounds.width/2)/(CGFloat(asset.pixelWidth)), ((UIScreen.mainScreen().bounds.height/2)/CGFloat(asset.pixelHeight)))
                    }
                    var size:CGSize = CGSizeMake((CGFloat(asset.pixelWidth)*minRatio),(CGFloat(asset.pixelHeight)*minRatio))
                    UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
                    result.drawInRect(CGRectMake(0, 0, size.width, size.height))
                    var final = UIGraphicsGetImageFromCurrentImageContext()
                    var image = iImage(uiimage: final)
                    self._selectediImages.append(image)
                    self._cacheImageComplete!++
                    println(self._cacheImageComplete)
                    if(self._cacheImageComplete == self._selectionCount)
                    {
                        self._processingImages = false
                        self.selectionCallback(self._selectediImages)
                    }
            }

        }
    }
4

2 回答 2

7

不要自己调整图像的大小——部分目的PHImageManager是为你做这件事。(它还缓存缩略图,以便您下次可以更快地获取它们,并在应用程序之间共享该缓存,这样您就不会最终有六个应用程序为您的整个库创建六个单独的 500MB 缩略图缓存。 )

func processImages() {
    _selectediImages = Array()
    _cacheImageComplete = 0
    for asset in _selectedAssets {
        let options = PHImageRequestOptions()
        options.deliveryMode = .FastFormat

        // request images no bigger than 1/3 the screen width
        let maxDimension = UIScreen.mainScreen().bounds.width / 3 * UIScreen.mainScreen().scale
        let size = CGSize(width: maxDimension, height: maxDimension)

        PHImageManager.defaultManager().requestImageForAsset(asset, targetSize: size, contentMode: .AspectFill, options: options)
            { result, info in
                // probably some of this code is unnecessary, too,
                // but I'm not sure what you're doing here so leaving it alone
                self._selectediImages.append(result)
                self._cacheImageComplete!++
                println(self._cacheImageComplete)
                if self._cacheImageComplete == self._selectionCount {
                    self._processingImages = false
                    self.selectionCallback(self._selectediImages)
                }
            }
        }
    }
}

显着变化:

  • 不要在主线程上同步请求图像。只是不要。
  • 将一个正方形的最大尺寸传递给requestImageForAsset使用AspectFill模式。这将为您提供一张可以裁剪以填充该正方形的图像,无论其纵横比是多少。
  • 您在这里按像素大小要求图像,屏幕大小以点为单位。乘以屏幕比例,否则您的图像将被像素化。(再一次,你要求FastFormat,所以无论如何你可能会得到模糊的图像。)
于 2014-12-10T19:03:53.310 回答
6

为什么说synchronous?显然,这会使事情慢下来。而且,synchronous绝对禁止在主线程上说!!!!阅读文档并遵守它们。这是这里的主要问题。

然后还有很多其他的考虑。基本上你使用这个调用都是错误的。删除 后synchronous,不要那样处理图像!请记住,此回调将被多次调用,因为图像提供的版本越来越好。你不能在这里做任何耗时的事情。

(另外,你为什么要调整图像的大小?如果你想要一个特定大小的图像,你应该在请求时询问那个大小。让图像获取器为你完成工作。)

于 2014-12-10T18:46:54.577 回答