PHAsset для UIImage
Я пытаюсь создать UIImage (например, миниатюру или что-то еще) из PHAsset, чтобы я мог передать его во что-то, что принимает UIImage. Я пробовал адаптировать решения, которые я нашел на SO (поскольку они просто прямо передают его в виде табличного представления или что-то в этом роде), но у меня нет успеха (скорее всего, потому что я не делаю это правильно).
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
}
printlns говорят мне, что строка manager.request ничего не делает прямо сейчас. Как мне получить его, чтобы дать мне актив как UIImage.
Спасибо.
Ответы
Ответ 1
Это сделало то, что мне было нужно, если это кому-то тоже понадобится.
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
}
Изменить: обновление Swift 3
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
}
Ответ 2
попробуйте это, это работает для меня, надеюсь, что это тоже поможет вам,
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
}
Ответ 3
Для 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
}
Ресурс: https://gist.github.com/lvterry/f062cf9ae13bca76b0c6#file-getassetthumbnail-swift
Ответ 4
Я бы предложил использовать Apple PHCachingImageManager (который наследуется от PHImageManager):
Объект PHCachingImageManager извлекает или генерирует данные изображения для фото или видео активов
Кроме того, PHCachingImageManager поддерживает лучший механизм кэширования.
Пример выборки эскиза синхронно:
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*
}
Кроме того, вы можете использовать PHCachingImageManager для кэшировать свои изображения для более быстрого ответа на пользовательский интерфейс:
Чтобы использовать диспетчер изображений кеширования:
-
Создайте экземпляр PHCachingImageManager. (Этот шаг заменяется с помощью общий экземпляр PHImageManager.)
-
Используйте методы класса PHASset для извлечения интересующих вас активов.
-
Чтобы подготовить изображения для этих активов, вызовите startCachingImagesForAssets: targetSize: contentMode: options: method с целевым размером, режимом содержимого и параметрами, которые вы планируете использовать, когда позже запрашивая изображения для каждого отдельного актива.
-
Когда вам нужно изображение для отдельного актива, вызовите requestImageForAsset: targetSize: contentMode: Варианты: ResultHandler: метод и передать те же параметры, которые вы использовали при подготовке этого активов.
Если запрашиваемый вами образ находится среди уже подготовленных, Объект PHCachingImageManager немедленно возвращает это изображение. В противном случае фотографии подготавливают изображение по запросу и кэшируют его позже использовать.
В нашем примере:
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)
Ответ 5
Проблема заключается в том, что requestImageForAsset является resultHandler, и этот блок кода происходит в будущем после того, как ваши функции уже были напечатаны и вернули ожидаемое значение. Я пришел к изменениям, чтобы показать вам это, а также предложить некоторые простые решения.
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")
}
Подробнее о замыканиях и дескрипторе завершения и функциях async в Документация Apple
Я надеюсь, что это поможет!