从 PHAsset 获取缩略图
Fetching thumbnails from PHAsset
我正在尝试从 PHAsset 获取缩略图以及其他一些信息。
这是一个简化的代码片段。
对于我从相机胶卷中检索到的所有图像,请执行以下操作:
static func fetchAsset(asset: PHAsset)
{
if(asset.mediaType == PHAssetMediaType.Image){
let screenScale: CGFloat = UIScreen.mainScreen().scale
let imageSize = CGSize(width: 100 * screenScale, height: 100 * screenScale)
let options: PHImageRequestOptions = PHImageRequestOptions()
options.deliveryMode = PHImageRequestOptionsDeliveryMode.FastFormat
options.resizeMode = PHImageRequestOptionsResizeMode.Fast
options.synchronous = false
PHImageManager.defaultManager().requestImageForAsset(asset,
targetSize: imageSize,
contentMode: PHImageContentMode.AspectFill,
options: options,
resultHandler: { (result, info) -> Void in
if (result != nil && result!.scale == screenScale) {
var newItemImage = MyImage(isLocal:true)
if let fname = asset.valueForKey("filename") as? String{
newItemImage.fileName = fname
}
newItemImage.thumbnail = result
asset.requestContentEditingInputWithOptions(PHContentEditingInputRequestOptions()) { (contentEditingInput, info) -> Void in
//Get full image
let url = contentEditingInput!.fullSizeImageURL
newItemImage.url = url
}
//DO SOMWTHING WITH IMAGE
}else
{
//DO SOMWTHING ELSE
}
})
}
}
现阶段我有两个问题:
- 最重要的一个,但我想这是结果。也需要
大量的处理能力和从光盘读取。它工作正常
模拟器。但是当我 运行 它在测试设备 (iPhone 5, 4S) 上时,
有 300-500 张图像,它会冻结一两分钟,同时获取
所有图像。我想它通过一个
一,调整它的大小并获取所有这些信息。有没有更简单的方法?就像使用 ALAsset 一样,我可以直接获取缩略图并且它飞得很快。
- 出于某种原因,它完成了两次工作。首先,它给了我我想要的东西,小缩略图 ~ 60 * 40 左右。一旦它
给了我,几秒钟后它进入另一个循环
并开始检索更高分辨率的图像,例如 960 * 640 左右,这就是冻结发生的地方。我不确定为什么会这样,但确实如此。
我们将不胜感激任何关于这两个问题的意见。
It does the job twice for some reason
因为这是它应该做的。正如您所发现的,从照片库中获取图像需要时间。因此,默认行为是我们尽快提供低分辨率图像,这样您就有东西可以显示;然后我们再次调用,可能多次,使用质量更好的图像版本。此外,提取是异步形成的。因此,完全有可能同时发生多个提取请求,这可能会导致您的代码开始绊倒自己的脚,正如您所发现的那样。
如果您不喜欢这样,请将获取选项 synchronous
设置为 true
— 但是您必须在后台队列中进行整个调用!通过在 serial 队列中执行此操作,您可以确保调用依次单独执行,并且每个图像将只传递一次。此外,那时(并且只有那时)你的 PHImageRequestOptions.DeliveryModeFastFormat
才会被遵守。在对收到的图像进行任何操作之前,不要忘记退回到主线程!
你也可以使用我写的这个扩展:
import Photos
extension PHAsset {
var thumbnailImage : UIImage {
get {
let manager = PHImageManager.default()
let option = PHImageRequestOptions()
var thumbnail = UIImage()
option.isSynchronous = true
manager.requestImage(for: self, targetSize: CGSize(width: 300, height: 300), contentMode: .aspectFit, options: option, resultHandler: {(result, info)->Void in
thumbnail = result!
})
return thumbnail
}
}
}
我正在尝试从 PHAsset 获取缩略图以及其他一些信息。 这是一个简化的代码片段。
对于我从相机胶卷中检索到的所有图像,请执行以下操作:
static func fetchAsset(asset: PHAsset)
{
if(asset.mediaType == PHAssetMediaType.Image){
let screenScale: CGFloat = UIScreen.mainScreen().scale
let imageSize = CGSize(width: 100 * screenScale, height: 100 * screenScale)
let options: PHImageRequestOptions = PHImageRequestOptions()
options.deliveryMode = PHImageRequestOptionsDeliveryMode.FastFormat
options.resizeMode = PHImageRequestOptionsResizeMode.Fast
options.synchronous = false
PHImageManager.defaultManager().requestImageForAsset(asset,
targetSize: imageSize,
contentMode: PHImageContentMode.AspectFill,
options: options,
resultHandler: { (result, info) -> Void in
if (result != nil && result!.scale == screenScale) {
var newItemImage = MyImage(isLocal:true)
if let fname = asset.valueForKey("filename") as? String{
newItemImage.fileName = fname
}
newItemImage.thumbnail = result
asset.requestContentEditingInputWithOptions(PHContentEditingInputRequestOptions()) { (contentEditingInput, info) -> Void in
//Get full image
let url = contentEditingInput!.fullSizeImageURL
newItemImage.url = url
}
//DO SOMWTHING WITH IMAGE
}else
{
//DO SOMWTHING ELSE
}
})
}
}
现阶段我有两个问题:
- 最重要的一个,但我想这是结果。也需要 大量的处理能力和从光盘读取。它工作正常 模拟器。但是当我 运行 它在测试设备 (iPhone 5, 4S) 上时, 有 300-500 张图像,它会冻结一两分钟,同时获取 所有图像。我想它通过一个 一,调整它的大小并获取所有这些信息。有没有更简单的方法?就像使用 ALAsset 一样,我可以直接获取缩略图并且它飞得很快。
- 出于某种原因,它完成了两次工作。首先,它给了我我想要的东西,小缩略图 ~ 60 * 40 左右。一旦它 给了我,几秒钟后它进入另一个循环 并开始检索更高分辨率的图像,例如 960 * 640 左右,这就是冻结发生的地方。我不确定为什么会这样,但确实如此。
我们将不胜感激任何关于这两个问题的意见。
It does the job twice for some reason
因为这是它应该做的。正如您所发现的,从照片库中获取图像需要时间。因此,默认行为是我们尽快提供低分辨率图像,这样您就有东西可以显示;然后我们再次调用,可能多次,使用质量更好的图像版本。此外,提取是异步形成的。因此,完全有可能同时发生多个提取请求,这可能会导致您的代码开始绊倒自己的脚,正如您所发现的那样。
如果您不喜欢这样,请将获取选项 synchronous
设置为 true
— 但是您必须在后台队列中进行整个调用!通过在 serial 队列中执行此操作,您可以确保调用依次单独执行,并且每个图像将只传递一次。此外,那时(并且只有那时)你的 PHImageRequestOptions.DeliveryModeFastFormat
才会被遵守。在对收到的图像进行任何操作之前,不要忘记退回到主线程!
你也可以使用我写的这个扩展:
import Photos
extension PHAsset {
var thumbnailImage : UIImage {
get {
let manager = PHImageManager.default()
let option = PHImageRequestOptions()
var thumbnail = UIImage()
option.isSynchronous = true
manager.requestImage(for: self, targetSize: CGSize(width: 300, height: 300), contentMode: .aspectFit, options: option, resultHandler: {(result, info)->Void in
thumbnail = result!
})
return thumbnail
}
}
}