PHAsset 到 UIImage
PHAsset to UIImage
我正在尝试从 PHAsset 创建一个 UIImage(如缩略图或其他东西),以便我可以将它传递到需要 UIImage 的东西中。我已经尝试过调整我在 SO 上找到的解决方案(因为它们都直接将它传递给 tableview 或其他东西),但我没有成功(可能是因为我做得不对)。
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 提供给我。
谢谢。
问题在于 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")
}
了解有关闭包和完成句柄以及异步函数的更多信息
希望对你有帮助!
这就是我需要它做的,以防万一有人也需要它。
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
}
我建议使用 Apple 的 PHCachingImageManager(继承自 PHImageManager):
A PHCachingImageManager object fetches or generates image data for photo or video assets
此外,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 来缓存您的图像以获得更快的UI响应:
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.
在我们的示例中:
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)
对于 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
试试这个对我有用,希望对你也有帮助,
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
}
Objective-c 基于 dcheng 答案的代码版本。
-(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;
}
Swift 4.
resizeMode
,deliveryMode
- 这些可以根据用户要求设置。
isNetworkAccessAllowed
- 将此设置为 "true" 以从云端获取图像
imageSize
- 要求的图片大小
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!)
})
}
简单的解决方案 (Swift 4.2)
方法一:
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
如果您只需要 PHAsset
中的 UIImage
,请使用此方法。
或
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?)
根据您的需要使用此方法UIImage
。
或
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")
})
完成后使用此方法进行通知。
方法二:
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
如果您想要 UIImage
和 PHAsset
的结果信息,请使用此方法
或
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?)
使用此方法获取所需数据。
Swift 5
extension PHAsset {
func getAssetThumbnail() -> UIImage {
let manager = PHImageManager.default()
let option = PHImageRequestOptions()
var thumbnail = UIImage()
option.isSynchronous = true
manager.requestImage(for: self,
targetSize: CGSize(width: self.pixelWidth, height: self.pixelHeight),
contentMode: .aspectFit,
options: option,
resultHandler: {(result, info) -> Void in
thumbnail = result!
})
return thumbnail
}
}
Swift 5 工作函数
func getImageForAsset(asset: PHAsset) -> UIImage {
let manager = PHImageManager.default
let option = PHImageRequestOptions()
var thumbnail = UIImage()
option.isSynchronous = true
manager().requestImage(for: asset, targetSize: CGSize(width: 100.0, height: 100.0), contentMode: .aspectFit, options: nil, resultHandler: {(result, info) -> Void in
thumbnail = result!
})
return thumbnail
}
我正在尝试从 PHAsset 创建一个 UIImage(如缩略图或其他东西),以便我可以将它传递到需要 UIImage 的东西中。我已经尝试过调整我在 SO 上找到的解决方案(因为它们都直接将它传递给 tableview 或其他东西),但我没有成功(可能是因为我做得不对)。
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 提供给我。
谢谢。
问题在于 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")
}
了解有关闭包和完成句柄以及异步函数的更多信息
希望对你有帮助!
这就是我需要它做的,以防万一有人也需要它。
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
}
我建议使用 Apple 的 PHCachingImageManager(继承自 PHImageManager):
A PHCachingImageManager object fetches or generates image data for photo or video assets
此外,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 来缓存您的图像以获得更快的UI响应:
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.
在我们的示例中:
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)
对于 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
试试这个对我有用,希望对你也有帮助,
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
}
Objective-c 基于 dcheng 答案的代码版本。
-(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;
}
Swift 4.
resizeMode
,deliveryMode
- 这些可以根据用户要求设置。
isNetworkAccessAllowed
- 将此设置为 "true" 以从云端获取图像
imageSize
- 要求的图片大小
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!)
})
}
简单的解决方案 (Swift 4.2)
方法一:
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
如果您只需要 PHAsset
中的 UIImage
,请使用此方法。
或
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?)
根据您的需要使用此方法UIImage
。
或
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")
})
完成后使用此方法进行通知。
方法二:
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
如果您想要 UIImage
和 PHAsset
或
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?)
使用此方法获取所需数据。
Swift 5
extension PHAsset {
func getAssetThumbnail() -> UIImage {
let manager = PHImageManager.default()
let option = PHImageRequestOptions()
var thumbnail = UIImage()
option.isSynchronous = true
manager.requestImage(for: self,
targetSize: CGSize(width: self.pixelWidth, height: self.pixelHeight),
contentMode: .aspectFit,
options: option,
resultHandler: {(result, info) -> Void in
thumbnail = result!
})
return thumbnail
}
}
Swift 5 工作函数
func getImageForAsset(asset: PHAsset) -> UIImage {
let manager = PHImageManager.default
let option = PHImageRequestOptions()
var thumbnail = UIImage()
option.isSynchronous = true
manager().requestImage(for: asset, targetSize: CGSize(width: 100.0, height: 100.0), contentMode: .aspectFit, options: nil, resultHandler: {(result, info) -> Void in
thumbnail = result!
})
return thumbnail
}