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 I found on SO (since they all just directly pass it into say a tableview or something), but I have no success (likely because I'm not doing it right).
func getAssetThumbnail(asset: PHAsset) -> UIImage {
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(retimage)
return retimage
}
The printlns are telling me that the manager.request line isn't doing anything right now. How do I get it to give me the asset as a UIImage.
Thanks.
Use this method if you only need UIImage from PHAsset . extension PHAsset { func image(targetSize: CGSize, contentMode: PHImageContentMode, options: PHImageRequestOptions?) -> UIImage { var thumbnail = UIImage() let imageManager = PHCachingImageManager() imageManager.
A representation of an image, video, or Live Photo in the Photos library.
This did what I needed it to do, in case anyone also needs this.
func getAssetThumbnail(asset: PHAsset) -> UIImage {
let manager = PHImageManager.defaultManager()
let option = PHImageRequestOptions()
var thumbnail = UIImage()
option.synchronous = true
manager.requestImageForAsset(asset, targetSize: CGSize(width: 100.0, height: 100.0), contentMode: .AspectFit, options: option, resultHandler: {(result, info)->Void in
thumbnail = result!
})
return thumbnail
}
func getAssetThumbnail(asset: PHAsset) -> UIImage {
let manager = PHImageManager.default()
let option = PHImageRequestOptions()
var thumbnail = UIImage()
option.isSynchronous = true
manager.requestImage(for: asset, targetSize: CGSize(width: 100, height: 100), contentMode: .aspectFit, options: option, resultHandler: {(result, info)->Void in
thumbnail = result!
})
return thumbnail
}
try this it works for me, hope it helps you too,
func getUIImage(asset: PHAsset) -> UIImage? {
var img: UIImage?
let manager = PHImageManager.default()
let options = PHImageRequestOptions()
options.version = .original
options.isSynchronous = true
manager.requestImageData(for: asset, options: options) { data, _, _, _ in
if let data = data {
img = UIImage(data: data)
}
}
return img
}
Simple Solution (Swift 4.2)
Method 1:
extension PHAsset {
var image : UIImage {
var thumbnail = UIImage()
let imageManager = PHCachingImageManager()
imageManager.requestImage(for: self, targetSize: CGSize(width: 100, height: 100), contentMode: .aspectFit, options: nil, resultHandler: { image, _ in
thumbnail = image!
})
return thumbnail
}
}
let image = asset.image
Use this method if you only need UIImage
from PHAsset
.
OR
extension PHAsset {
func image(targetSize: CGSize, contentMode: PHImageContentMode, options: PHImageRequestOptions?) -> UIImage {
var thumbnail = UIImage()
let imageManager = PHCachingImageManager()
imageManager.requestImage(for: self, targetSize: targetSize, contentMode: contentMode, options: options, resultHandler: { image, _ in
thumbnail = image!
})
return thumbnail
}
}
let image = asset.image(targetSize: CGSize, contentMode: PHImageContentMode, options: PHImageRequestOptions?)
Use this method for your desired UIImage
.
OR
extension PHAsset {
func image(completionHandler: @escaping (UIImage) -> ()){
var thumbnail = UIImage()
let imageManager = PHCachingImageManager()
imageManager.requestImage(for: self, targetSize: CGSize(width: 100, height: 100), contentMode: .aspectFit, options: nil, resultHandler: { img, _ in
thumbnail = img!
})
completionHandler(thumbnail)
}
}
let image = asset.image(completionHandler: {(img) in
print("Finished")
})
Use this method for notify after completion.
Method 2:
extension PHAsset {
var data : (UIImage, [AnyHashable : Any]) {
var img = UIImage(); var information = [AnyHashable : Any](); let imageManager = PHCachingImageManager()
imageManager.requestImage(for: self, targetSize: CGSize(width: 100, height: 100), contentMode: .aspectFit, options: nil, resultHandler: { image,info in
img = image!
information = info!
})
return (img,information)
}
}
let image_withData : (UIImage, [AnyHashable : Any]) = asset.data
Use this method if you want UIImage
And Result Info of PHAsset
OR
extension PHAsset {
func data(targetSize: CGSize, contentMode: PHImageContentMode, options: PHImageRequestOptions?) -> (UIImage, [AnyHashable : Any]) {
var img = UIImage(); var information = [AnyHashable : Any](); let imageManager = PHCachingImageManager()
imageManager.requestImage(for: self, targetSize: targetSize, contentMode: contentMode, options: options, resultHandler: { image,info in
img = image!
information = info!
})
return (img,information)
}
}
let data = asset?.data(targetSize: CGSize, contentMode: PHImageContentMode, options: PHImageRequestOptions?)
Use this method for your desired Data.
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:
Create a PHCachingImageManager instance. (This step replaces using the shared PHImageManager instance.)
Use PHAsset class methods to fetch the assets you’re interested in.
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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With