J'essaie de créer un UIImage (comme une vignette ou quelque chose de ce genre) à partir d'un PHAsset afin de pouvoir le transférer dans quelque chose qui prend un UIImage. J'ai essayé d'adapter les solutions que j'ai trouvées sur SO (puisqu'elles passent toutes directement dans une table, par exemple), mais je n'ai aucun succès (probablement parce que je ne le fais pas correctement).
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
}
Les imprimeurs me disent que la ligne manager.request ne fait rien pour le moment. Comment puis-je l'obtenir pour me donner l'actif en tant que UIImage.
Merci.
Cela a fait ce que je devais faire, au cas où quelqu'un en aurait aussi besoin.
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
}
essayez cela cela fonctionne pour moi, j'espère que cela vous aide aussi,
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
}
Pour 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
}
Ressources: https://Gist.github.com/lvterry/f062cf9ae13bca76b0c6#file-getassetthumbnail-Swift
Je suggérerais d'utiliser PHCachingImageManager d'Apple (qui hérite de PHImageManager):
Un objet PHCachingImageManager récupère ou génère des données d'image pour des éléments photo ou vidéo.
En outre, PHCachingImageManager prend en charge un meilleur mécanisme de mise en cache.
Exemple de récupération d'une miniature synchrone:
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*
}
De plus, vous pouvez utiliser PHCachingImageManager pour mettre en cache vos images pour une réponse plus rapide de l'interface utilisateur:
Pour utiliser un gestionnaire d'images en cache:
Créez une instance de PHCachingImageManager. (Cette étape remplace l'utilisation de l'instance PHImageManager partagée Partagée.)
Utilisez les méthodes de classe PHAsset pour récupérer les actifs qui vous intéressent.
Pour préparer des images pour ces éléments, appelez le startCachingImagesForAssets: targetSize: contentMode: options: method avec la taille cible, le mode de contenu et les options que vous prévoyez d'utiliser quand demander plus tard des images pour chaque élément individuel.
Lorsque vous avez besoin d’une image pour un élément individuel, appelez le requestImageForAsset: targetSize: contentMode: options: resultHandler: méthode, et transmettez les mêmes paramètres que vous avez utilisés lors de la préparation de cette atout.
Si l'image que vous demandez fait partie de celles déjà préparées, le fichier L'objet PHCachingImageManager renvoie immédiatement cette image . Sinon, Photos prépare l'image à la demande et la met en cache pour plus tard utilisation.
Dans notre exemple:
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)
Solution simple (Swift 4.2)
Méthode 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
Utilisez cette méthode si vous avez uniquement besoin de UIImage
à partir de PHAsset
.
OU
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?)
Utilisez cette méthode pour votre UIImage
désirée.
OU
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")
})
Utilisez cette méthode pour notifier après la fin.
Méthode 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
Utilisez cette méthode si vous souhaitez UIImage
et les informations de résultat de PHAsset
OU
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?)
Utilisez cette méthode pour les données souhaitées.
Le problème est que requestImageForAsset est un resultHandler et que ce bloc de code se produit ultérieurement lorsque vos fonctions ont déjà été imprimées et ont renvoyé la valeur que vous attendiez. Je suis venu des changements pour vous montrer ce qui se passe et suggère également des solutions simples.
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")
}
En savoir plus sur les fermetures, la gestion des travaux d’achèvement et les fonctions asynchrones à Documentation Apple
J'espère que ça vous aide!
Swift 4.
resizeMode
, deliveryMode
- Ces options peuvent être définies en fonction des besoins de l'utilisateur.
isNetworkAccessAllowed
- définissez ceci sur "true" pour récupérer des images du nuage
imageSize
- taille d'image requise
func getImageFromAsset(asset:PHAsset,imageSize:CGSize, callback:@escaping (_ result:UIImage) -> Void) -> Void{
let requestOptions = PHImageRequestOptions()
requestOptions.resizeMode = PHImageRequestOptionsResizeMode.fast
requestOptions.deliveryMode = PHImageRequestOptionsDeliveryMode.highQualityFormat
requestOptions.isNetworkAccessAllowed = true
requestOptions.isSynchronous = true
PHImageManager.default().requestImage(for: asset, targetSize: imageSize, contentMode: PHImageContentMode.default, options: requestOptions, resultHandler: { (currentImage, info) in
callback(currentImage!)
})
}
Version du code Objective-c basée sur dcheng answer.
-(UIImage *)getAssetThumbnail:(PHAsset * )asset {
PHImageRequestOptions *options = [[PHImageRequestOptions alloc]init];
options.synchronous = true;
__block UIImage *image;
[PHCachingImageManager.defaultManager requestImageForAsset:asset targetSize:CGSizeMake(100, 100) contentMode:PHImageContentModeAspectFit options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
image = result;
}];
return image;
}