PHAsset с объектами UIImage

Я пытаюсь создать UIImage (например, эскиз или что-то еще) из PHAsset, чтобы я мог передать его во что-то, что принимает 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
}

println кодом, который передает мне говорят, что менеджер.линия запроса сейчас ничего не делает. Как я могу получить его, чтобы дать мне актив в качестве Объектами UIImage.

спасибо.

7 ответов


Это сделало то, что мне нужно было сделать, если кому-то это тоже нужно.

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
}

Edit: 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
}

попробуйте это работает для меня, надеюсь, это поможет тебе,

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
}

Для 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


Я бы предложил использовать 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:параметры: метод с мишенью размер, режим содержимого и параметры, которые планируется использовать позже запрашиваю изображения для каждого отдельного актива.

  4. когда вам нужно изображение для отдельного актива, вызовите 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)

проблема в том, что 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

Я надеюсь, что помогает!


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

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