6

这看起来很容易,但缺乏文档使得这个问题无法猜测。

我的应用程序的 icloud 驱动器上有图片和视频,我想创建这些资产的缩略图。我说的是 iCloud Drive 上的资产,而不是相机胶卷内的 iCloud 照片流。我说的是真正的 iCloud Drive 文件夹。

与图像相比,从视频创建缩略图“容易”。你只需要 2 周的时间来弄清楚它是如何工作的,考虑到苹果写的糟糕的文档,但图像中的缩略图似乎是不可能的。

我现在拥有的是一组NSMetadataItems,每个都描述 iCloud 文件夹上的一个项目。

这些是我迄今为止尝试过的不起作用的方法:


方法一

[fileURL startAccessingSecurityScopedResource];

NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] init];
__block NSError *error;

[coordinator coordinateReadingItemAtURL:fileURL
                                options:NSFileCoordinatorReadingImmediatelyAvailableMetadataOnly
                                  error:&error
                             byAccessor:^(NSURL *newURL) {
                               NSDictionary *thumb;
                               BOOL success = [newURL getResourceValue:&thumb forKey:NSURLThumbnailDictionaryKey error:&error];

                               UIImage *thumbnail = thumb[NSThumbnail1024x1024SizeKey];



                             }];

[fileURL stopAccessingSecurityScopedResource];

这种方法的结果非常棒。准备好了吗?我们开始:success = YESerror = nilthumbnail = nil


另一种方法

AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:fileURL
                                            options:nil];

AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset];

imageGenerator.appliesPreferredTrackTransform = YES;

CMTime time = CMTimeMake(0, 60); // time range in which you want
NSValue *timeValue = [NSValue valueWithCMTime:time];

[imageGenerator generateCGImagesAsynchronouslyForTimes:@[timeValue] completionHandler:^(CMTime requestedTime, CGImageRef image, CMTime actualTime, AVAssetImageGeneratorResult result, NSError * error) {

  thumbnail = [[UIImage alloc] initWithCGImage:image];

}];

error = The requested URL was not found on this server.thumbnail = nil

此方法似乎仅适用于视频。我正在尝试这个以防万一。这种方法与图像等效吗?


原始方法

NSData *tempData = [NSData dataWithContentsOfUrl:tempURL];

NOPE - 数据 = 无


方法 4

第四种可能的方法是使用ALAsset,但在 iOS 9 上已弃用。

我认为所有这些方法都失败了,因为如果资源是本地的,它们就可以工作(无论错误与否)。关于如何下载图像以便获得缩略图的任何想法?

还有其他想法吗?

谢谢


编辑:经过几次测试,我发现方法 1 是唯一似乎朝着正确方向的方法。这种方法效果不佳,有时会抓取图标,但大部分时间都不起作用。


还有一点就是这个。无论人们向我建议什么,他们总是说要下载整个图像以获取缩略图。我不认为这是要走的路。看看如何获​​取视频缩略图。您无需下载整个视频以获取其缩略图。

所以这个问题仍然悬而未决。

4

4 回答 4

3

Photos-Framework 或 AssetsLibrary 在这里不起作用,因为您必须先将 iCloud Drive 照片导入 PhotoLibrary 才能使用这两个框架的任何方法。

你应该看的是 ImageIO: Get the content of the iCloud Drive Photo as NSData 然后像这样继续:

CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)(imageData), NULL );

NSDictionary* thumbOpts = [NSDictionary dictionaryWithObjectsAndKeys:
                                    (id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailWithTransform,
                                    (id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailFromImageAlways,
                                    [NSNumber numberWithInt:160],(id)kCGImageSourceThumbnailMaxPixelSize,
                                    nil];

CGImageRef  thumbImageRef = CGImageSourceCreateThumbnailAtIndex(source,0,(__bridge CFDictionaryRef)thumbOpts);

UIImage *thumbnail = [[UIImage alloc] initWithCGImage: thumbImageRef];
于 2015-09-17T00:34:39.450 回答
2

在测试了几种解决方案之后,似乎效果更好的一个是这个:

[fileURL startAccessingSecurityScopedResource];

NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] init];
__block NSError *error;

[coordinator coordinateReadingItemAtURL:fileURL
                                options:NSFileCoordinatorReadingImmediatelyAvailableMetadataOnly
                                  error:&error
                             byAccessor:^(NSURL *newURL) {
                               NSDictionary *thumb;
                               BOOL success = [newURL getResourceValue:&thumb forKey:NSURLThumbnailDictionaryKey error:&error];

                               UIImage *thumbnail = thumb[NSThumbnail1024x1024SizeKey];



                             }];

[fileURL stopAccessingSecurityScopedResource];

这个解决方案并不完美。有时它会无法显示缩略图,但我无法找到任何其他 100% 有效的解决方案。其他人比这更糟糕。

于 2015-09-21T08:11:34.560 回答
1

这对我有用。它有点不同

func genereatePreviewForOnce(at size: CGSize,completionHandler: @escaping (UIImage?) -> Void) {

        _ = fileURL.startAccessingSecurityScopedResource()

        let fileCoorinator = NSFileCoordinator.init()

        fileCoorinator.coordinate(readingItemAt: fileURL, options: .immediatelyAvailableMetadataOnly, error: nil) { (url) in

            if let res = try? url.resourceValues(forKeys: [.thumbnailDictionaryKey]),

                let dict = res.thumbnailDictionary {

                let image = dict[.NSThumbnail1024x1024SizeKey]

                completionHandler(image)

            } else {

                fileURL.removeCachedResourceValue(forKey: .thumbnailDictionaryKey)

                completionHandler(nil)

            }

            fileURL.stopAccessingSecurityScopedResource()

        }

    }
于 2018-05-17T06:06:09.790 回答
0

看起来您是在事后生成缩略图。如果这是您的文档并且您正在使用 UIDocument,fileAttributesToWriteToURL:forSaveOperation:error:请在保存文档时覆盖以插入缩略图。

于 2017-11-10T16:48:44.587 回答