PHAsset to UIImage

后端 未结 9 2060
不思量自难忘°
不思量自难忘° 2020-12-07 22:23

I\'m attempting to create a UIImage (like a thumbnail or something) from a PHAsset so that I can pass it into something that takes a UIImage. I\'ve tried adapting solutions

相关标签:
9条回答
  • 2020-12-07 22:48

    I'd suggest using Apple's PHCachingImageManager (that inherits from PHImageManager):

    A PHCachingImageManager object fetches or generates image data for photo or video assets

    Also, PHCachingImageManager support a better caching mechanism.

    Example of fetching a thumbnail synchronous:

    let options = PHImageRequestOptions()
    options.deliveryMode = .HighQualityFormat
    options.synchronous = true // Set it to false for async callback
    
    let imageManager = PHCachingImageManager()
    imageManager.requestImageForAsset(YourPHAssetVar,
                                      targetSize: CGSizeMake(CGFloat(160), CGFloat(160)),
                                      contentMode: .AspectFill,
                                      options: options,
                                      resultHandler: { (resultThumbnail : UIImage?, info : [NSObject : AnyObject]?) in
    
                                                       // Assign your thumbnail which is the *resultThumbnail*
                                                      }
    

    In addition, you can use PHCachingImageManager to cache your images for faster UI response:

    To use a caching image manager:

    1. Create a PHCachingImageManager instance. (This step replaces using the shared PHImageManager instance.)

    2. Use PHAsset class methods to fetch the assets you’re interested in.

    3. To prepare images for those assets, call the startCachingImagesForAssets:targetSize:contentMode:options: method with the target size, content mode, and options you plan to use when later requesting images for each individual asset.

    4. When you need an image for an individual asset, call the requestImageForAsset:targetSize:contentMode:options:resultHandler: method, and pass the same parameters you used when preparing that asset.

    If the image you request is among those already prepared, the PHCachingImageManager object immediately returns that image. Otherwise, Photos prepares the image on demand and caches it for later use.

    In our example:

    var phAssetArray : [PHAsset] = []
    
    for i in 0..<assets.count
    {
      phAssetArray.append(assets[i] as! PHAsset)
    }
    
    let options = PHImageRequestOptions()
    options.deliveryMode = .Opportunistic
    options.synchronous = false
    
    self.imageManager.startCachingImagesForAssets(phAssetArray,
                                                  targetSize: CGSizeMake(CGFloat(160), CGFloat(160)),
                                                  contentMode: .AspectFill,
                                                  options: options)
    
    0 讨论(0)
  • 2020-12-07 22:54

    For Swift 3.0.1:

    func getAssetThumbnail(asset: PHAsset, size: CGFloat) -> UIImage {
        let retinaScale = UIScreen.main.scale
        let retinaSquare = CGSize(width: size * retinaScale, height: size * retinaScale)//(size * retinaScale, size * retinaScale)
        let cropSizeLength = min(asset.pixelWidth, asset.pixelHeight)
        let square = CGRect(x:0, y: 0,width: CGFloat(cropSizeLength),height: CGFloat(cropSizeLength))
        let cropRect = square.applying(CGAffineTransform(scaleX: 1.0/CGFloat(asset.pixelWidth), y: 1.0/CGFloat(asset.pixelHeight)))
    
        let manager = PHImageManager.default()
        let options = PHImageRequestOptions()
        var thumbnail = UIImage()
    
        options.isSynchronous = true
        options.deliveryMode = .highQualityFormat
        options.resizeMode = .exact
        options.normalizedCropRect = cropRect
    
        manager.requestImage(for: asset, targetSize: retinaSquare, contentMode: .aspectFit, options: options, resultHandler: {(result, info)->Void in
            thumbnail = result!
        })
        return thumbnail
    }
    

    Resource : https://gist.github.com/lvterry/f062cf9ae13bca76b0c6#file-getassetthumbnail-swift

    0 讨论(0)
  • 2020-12-07 22:55

    The problem is that requestImageForAsset is a resultHandler and this block of code happens in the future after your functions has already printed and returned the value you was expecting. I did come changes to show you this happening and also suggest some simple solutions.

    func getAssetThumbnail(asset: PHAsset) {
        var retimage = UIImage()
        println(retimage)
        let manager = PHImageManager.defaultManager()
        manager.requestImageForAsset(asset, targetSize: CGSize(width: 100.0, height: 100.0), contentMode: .AspectFit, options: nil, resultHandler: {
        (result, info)->Void in
                retimage = result
          println("This happens after")
          println(retimage)
          callReturnImage(retimage) // <- create this method
        })
        println("This happens before")
    }
    

    Learn more about closures and completion handle and async funcs at Apple documentation

    I hope that helps you!

    0 讨论(0)
提交回复
热议问题