简体   繁体   English

如何使用Photo Kit获取专辑海报图像?

[英]How to fetch album poster image using Photo Kit?

When using Assets Library you could fetch the album's poster image from ALAssetsGroup. 使用资产库时,您可以从ALAssetsGroup获取相册的海报图像。 How do you achieve the same when using Photos Framework (Photo kit)? 使用照片框架(照片工具包)时,如何实现同样的目标?

I do it this way. 我是这样做的。 In the method cellForRowAtIndexPath: in albums tableView add the following code. 在方法cellForRowAtIndexPath中:在相册tableView中添加以下代码。

Objective C: 目标C:

    PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
    fetchOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];
    PHFetchResult *fetchResult = [PHAsset fetchKeyAssetsInAssetCollection:[self.assetCollections objectAtIndex:indexPath.row] options:fetchOptions];
        PHAsset *asset = [fetchResult firstObject];
        PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
        options.resizeMode = PHImageRequestOptionsResizeModeExact;

        CGFloat scale = [UIScreen mainScreen].scale;
        CGFloat dimension = 78.0f;
        CGSize size = CGSizeMake(dimension*scale, dimension*scale);

        [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:size contentMode:PHImageContentModeAspectFill options:options resultHandler:^(UIImage *result, NSDictionary *info) {
        dispatch_async(dispatch_get_main_queue(), ^{
            cell.imageView.image = result;
        });

        }];

Swift 3: 斯威夫特3:

let fetchOptions = PHFetchOptions()
let descriptor = NSSortDescriptor(key: "creationDate", ascending: true)
fetchOptions.sortDescriptors = [descriptor]

let fetchResult = PHAsset.fetchKeyAssets(in: assets[indexPath.row], options: fetchOptions)

guard let asset = fetchResult?.firstObject else {
    return
}

let options = PHImageRequestOptions()
options.resizeMode = .exact

let scale = UIScreen.main.scale
let dimension = CGFloat(78.0)
let size = CGSize(width: dimension * scale, height: dimension * scale)


PHImageManager.default().requestImage(for: asset, targetSize: size, contentMode: .aspectFill, options: options) { (image, info) in
    DispatchQueue.main.async {
        cell.imageView.image = image
    }
}

Edit: Looks like fetchKeyAssetsInAssetCollection does not always return correct results (most recently captured images/videos). 编辑:看起来fetchKeyAssetsInAssetCollection并不总是返回正确的结果(最近捕获的图像/视频)。 The definition of keyAssets is vaguely defined by apple . keyAssets的定义由apple模糊地定义。 Better use 更好用

+ (PHFetchResult *)fetchAssetsInAssetCollection:(PHAssetCollection *)assetCollection options:(PHFetchOptions *)options

to get the fetch results array and then get the firstObject from the fetch results as described before. 获取获取结果数组,然后如前所述从获取结果中获取firstObject。 This will certainly return the correct results. 这肯定会返回正确的结果。 :) :)

It is a very simple thing... 这是一件非常简单的事......

    PHFetchOptions *userAlbumsOptions = [PHFetchOptions new];
    userAlbumsOptions.predicate = [NSPredicate predicateWithFormat:@"estimatedAssetCount > 0"];

    PHFetchResult *userAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAny options:userAlbumsOptions];

    [userAlbums enumerateObjectsUsingBlock:^(PHAssetCollection *collection, NSUInteger idx, BOOL *stop) {
    NSLog(@"album title %@", collection.localizedTitle);
    PHFetchResult *assetsFetchResult = [PHAsset fetchAssetsInAssetCollection:collection options:nil];
    PHAsset *asset = [assetsFetchResult objectAtIndex:0];
    NSInteger retinaMultiplier = [UIScreen mainScreen].scale;
    CGSize retinaSquare = CGSizeMake(80 * retinaMultiplier, 80 * retinaMultiplier);

    [[SDWebImageManager sharedManager] downloadImageWithURL:[NSURL URLWithString:asset.localIdentifier] options:SDWebImageProgressiveDownload targetLocalAssetSize:retinaSquare progress:^(NSInteger receivedSize, NSInteger expectedSize) {

    } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
        if (image) {
            albumCoverImg.image = image;
        }
    }];
}];

and if you have not updated SDWebImage classed then load image as a normal way. 如果您还没有更新SDWebImage,则以正常方式加载图像。

Here's what I'm using now. 这就是我现在正在使用的内容。 It handles different types of photo collections and the case when key asset is missing. 它处理不同类型的照片集和缺少关键资产的情况。

static func fetchThumbnail(collection: PHCollection, targetSize: CGSize, completion: @escaping (UIImage?) -> ()) {

    func fetchAsset(asset: PHAsset, targetSize: CGSize, completion: @escaping (UIImage?) -> ()) {
        let options = PHImageRequestOptions()
        options.deliveryMode = PHImageRequestOptionsDeliveryMode.highQualityFormat
        options.isSynchronous = false
        options.isNetworkAccessAllowed = true

        // We could use PHCachingImageManager for better performance here
        PHImageManager.default().requestImage(for: asset, targetSize: targetSize, contentMode: .default, options: options, resultHandler: { (image, info) in
            completion(image)
        })
    }

    func fetchFirstImageThumbnail(collection: PHAssetCollection, targetSize: CGSize, completion: @escaping (UIImage?) -> ()) {
        // We could sort by creation date here if we want
        let assets = PHAsset.fetchAssets(in: collection, options: PHFetchOptions())
        if let asset = assets.firstObject {
            fetchAsset(asset: asset, targetSize: targetSize, completion: completion)
        } else {
            completion(nil)
        }
    }

    if let collection = collection as? PHAssetCollection {
        let assets = PHAsset.fetchKeyAssets(in: collection, options: PHFetchOptions())

        if let keyAsset = assets?.firstObject {
            fetchAsset(asset: keyAsset, targetSize: targetSize) { (image) in
                if let image = image {
                    completion(image)
                } else {
                    fetchFirstImageThumbnail(collection: collection, targetSize: targetSize, completion: completion)
                }
            }
        } else {
            fetchFirstImageThumbnail(collection: collection, targetSize: targetSize, completion: completion)
        }
    } else if let collection = collection as? PHCollectionList {
        // For folders we get the first available thumbnail from sub-folders/albums
        // possible improvement - make a "tile" thumbnail with 4 images
        let inner = PHCollection.fetchCollections(in: collection, options: PHFetchOptions())
        inner.enumerateObjects { (innerCollection, idx, stop) in
            self.fetchThumbnail(collection: innerCollection, targetSize: targetSize, completion: { (image) in
                if image != nil {
                    completion(image)
                    stop.pointee = true
                } else if idx >= inner.count - 1 {
                    completion(nil)
                }
            })
        }
    } else {
        // We shouldn't get here
        completion(nil)
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM