PHAsset到UIImage

时间:2015-06-12 20:58:22

标签: swift phasset

我正在尝试从PHAsset创建一个UIImage(如缩略图或其他东西),这样我就可以将它传递给带有UIImage的东西。我已经尝试调整我在SO上找到的解决方案(因为他们只是将它直接传递到tableview或其他东西),但我没有成功(可能因为我做得不对)。

 from operator import add
 words = ["one", "two", "two", "three", "three", "three"]
 wordsPairRDD = sc.parallelize(words).map(lambda word: (word, 1))
      .reduceByKey(add)
      .collect()

printlns告诉我,manager.request行现在没有做任何事情。如何让它作为UIImage给我资产。

感谢。

10 个答案:

答案 0 :(得分:76)

这就是我需要它做的事情,万一有人也需要它。

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
}

答案 1 :(得分:20)

试试这个对我有用,希望它对你也有帮助,

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
}

答案 2 :(得分:7)

我建议使用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 缓存图片以加快UI响应速度:

  

使用缓存图片管理器:

     
      
  1. 创建PHCachingImageManager实例。 (此步骤替换使用   共享PHImageManager实例。)

  2.   
  3. 使用PHAsset类方法获取您感兴趣的资产。

  4.   
  5. 要为这些资产准备图像,请致电   startCachingImagesForAssets:targetSize:contentMode:options:method   具有您计划在何时使用的目标大小,内容模式和选项   稍后请求每个资产的图像。

  6.   
  7. 当您需要单个资产的图片时,请致电   requestImageForAsset:的targetSize:contentMode:选项:resultHandler:   方法,并传递您在准备时使用的相同参数   资产。

  8.         

    如果您要求的图像是已经准备好的图像,那么   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)

答案 3 :(得分:7)

对于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 :(得分:6)

简单解决方案(Swift 4.2)

方法1:

factor_cmap

如果您只需要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 中的UIImage,请使用此方法。

OR

PHAsset

对所需的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?) 使用此方法。

OR

UIImage

使用此方法在完成后进行通知。

方法2:

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的结果信息,请使用此方法

OR

PHAsset

使用此方法获取所需的数据。

答案 5 :(得分:4)

问题是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")
}

Apple documentation

了解有关闭包和完成句柄以及异步函数的详情

我希望能帮到你!

答案 6 :(得分:4)

斯威夫特4。

resizeModedeliveryMode - 可以根据用户要求进行设置。

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!)
    })
}

答案 7 :(得分:3)

快捷键5

plot_df <- dataset %>%
  group_by(country) %>%
  filter(!is.na(female_head_gov), female_head_gov != "Don't know") %>%
  mutate(female_head_gov = fct_collapse(female_head_gov,
                                        `Agree/strongly agree` = c("I strongly agree", 
                                                             "I agree"),
                                        `Disagree/strongly disagree` = c("I disagree", 
                                                                     "I strongly disagree"))
  ) %>%
  count(female_head_gov) %>%
  mutate(prop = n / sum(n))

  plot_df$country <- fct_reorder(plot_df$country, plot_df$prop, function(x) -x[1])
  ggplot(plot_df, aes(country, prop, fill = female_head_gov)) +
  geom_col(position = "fill")

答案 8 :(得分:1)

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;
  }

答案 9 :(得分:0)

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
    }