5

I am working with the ALAssetLibrary to get the images from my camera roll for a custom view I am making. Doing so was pretty simple:

library.enumerateGroupsWithTypes(ALAssetsGroupType(ALAssetsGroupSavedPhotos), usingBlock: {
        (group: ALAssetsGroup?, stop: UnsafeMutablePointer<ObjCBool>) in
        if group != nil {
            group!.setAssetsFilter(ALAssetsFilter.allPhotos())
            var indexSet = NSIndexSet(indexesInRange: NSMakeRange(0, group!.numberOfAssets() - 1))
            group!.enumerateAssetsAtIndexes(indexSet, options: nil, usingBlock: {
                (result: ALAsset!, index: Int, stop: UnsafeMutablePointer<ObjCBool>) in
                if (result != nil) {
                    var alAssetRapresentation: ALAssetRepresentation = result.defaultRepresentation()
                    var url = alAssetRapresentation.url()
                    var iRef = alAssetRapresentation.fullResolutionImage().takeUnretainedValue()
                    var image = UIImage(CGImage: iRef)
                }
            })
        }
        }) { (NSError) -> Void in
    }

All this works great in the simulator. However on a device, getting the fullResolutionImage() proves to be way to memory intensive on the device and causes crashes. I figured that makes perfect sense, dozens of high res images all loaded into memory is a terrible idea, so I'd like to scale the quality back and only show the thumbnail of the image. Only issue is that there is no simple way I've found to get a thumbnail from the AlAssetRepresentation.

I am trying to work with the CGImageSourceCreateThumbnailAtIndex to create a thumbnail but have been very confused on how to do this.

Any help is much appreciated!

Unome
  • 6,750
  • 7
  • 45
  • 87

1 Answers1

4

Here's an example (there might be some minor compilation issues, depending what version of Swift you are using):

let src = CGImageSourceCreateWithURL(url, nil)
let scale = UIScreen.mainScreen().scale
let w = // desired display width, multiplied by scale
let d : [NSObject:AnyObject] = [
    kCGImageSourceShouldAllowFloat : true,
    kCGImageSourceCreateThumbnailWithTransform : true,
    kCGImageSourceCreateThumbnailFromImageAlways : true,
    kCGImageSourceThumbnailMaxPixelSize : w
]
let imref = CGImageSourceCreateThumbnailAtIndex(src, 0, d)
let im = UIImage(CGImage: imref, scale: scale, orientation: .Up)!

However, note that you should not be using ALAssetsLibrary any longer. It is deprecated in iOS 9. Switch to Photo Kit, and welcome to the modern world! Now you can call PHImageManager.defaultManager().requestImageForAsset, which allows you to supply a targetSize for the desired image.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Beautiful! So PhotoKit is what I should be using :D – Unome Aug 24 '15 at 19:50
  • Absolutely. Your desire to load the image at the reduced size is commendable, and CGImageSourceCreateThumbnailAtIndex is a great way to do it, but in this situation you don't have to do that; Photo Kit takes care of the whole thing for you. – matt Aug 24 '15 at 19:55
  • Fantastic. I'm going to use PhotoKit then, Thx! + 1 Is there any good material on how to enumerate the users photos using PhotoKit you can point me to? Thats where I'm at now. – Unome Aug 24 '15 at 19:56
  • @matt I am wondering about the scale, meaning, is the CGImageSourceCreateThumbnailAtIndex going to take into consideration the correct scale as it creates the thumbnail? Does the scale only matter when then creating the UIImage? – zumzum Feb 11 '16 at 11:57
  • CGImage has no scale, @zumzum It is just a bitmap. That is the reason for my comment about how to get `w` – matt Feb 11 '16 at 15:57