web-dev-qa-db-ja.com

UIImageへのPHAsset

PHAssetからUIImage(サムネイルなど)を作成して、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としてアセットを取得するにはどうすればよいですか。

ありがとう。

48
dcheng

誰もがこれを必要とする場合、これは私がそれをするために必要なことをしました。

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 update

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
}
80
dcheng

これが私のために働くことを試してください、それがあなたにも役立つことを願って、

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
}
21
Patel Jigar

シンプルなソリューション(Swift 4.2)

方法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 

UIImageからの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?)

目的の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")
})

このメソッドは、完了後に通知するために使用します。

方法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

UIImagePHAssetの結果情報が必要な場合は、このメソッドを使用します

[〜#〜]または[〜#〜]

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?)

目的のデータにこのメソッドを使用します。

8
ZAFAR007

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

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. PHAssetクラスメソッドを使用して、興味のあるアセットを取得します。

  3. それらのアセットの画像を準備するには、ターゲットサイズ、コンテンツモード、および後で個々のアセットの画像をリクエストするときに使用するオプションを指定してstartCachingImagesForAssets:targetSize:contentMode:options:メソッドを呼び出します。

  4. 個々のアセットに画像が必要な場合は、requestImageForAsset:targetSize:contentMode:options:resultHandler:メソッドを呼び出し、そのアセットを準備するときに使用したのと同じパラメーターを渡します。

要求した画像が既に準備されている画像の場合、PHCachingImageManagerオブジェクトはその画像をすぐに返します。それ以外の場合、Photosはオンデマンドで画像を準備し、後で使用するためにキャッシュします。

この例では:

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)
7
OhadM

スイフト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!)
    })
}
6
Thomas Paul

問題は、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ドキュメント でクロージャーと完了ハンドルと非同期関数の詳細をご覧ください

お役に立てばと思います!

4
Icaro

Dcheng回答に基づくコードのObjective-cバージョン。

-(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;
  }
1
Saikiran K