【问题标题】:How to generate thumbnails of images on iCloud Drive?如何在 iCloud Drive 上生成图像缩略图?
【发布时间】:2015-12-06 04:04:59
【问题描述】:

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

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

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

我现在拥有的是一组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 是唯一似乎方向正确的方法。这种方法效果不佳,有时会抓取图标,但大部分时间都不起作用。


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

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

【问题讨论】:

  • 是的,但本文讨论的是PHAssets。 PH 表示照片框架,我认为该框架无法从 iCloud Drive 中检索内容。我说的是 iCloud 资产。我不确定这两者之间的关系。我从 iCloud 得到的是一堆NSMetadataItems。如果您知道如何将 NSMetadataItem 转换为 PHAsset 项目,我已经多年了。

标签: ios thumbnails photosframework phasset icloud-drive


【解决方案1】:

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

你应该看的是 ImageIO: 将 iCloud Drive Photo 的内容作为 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];

【讨论】:

  • 好的,但是如何获取 imageData?这就是我所需要的 ? 我记得你说我的回答是 [NSData dataWithContentsOfUrl:tempURL]; 给我 nil。
  • 你检查过,你的 NSMetaDataItem 实际上是从 iCloud 下载的吗? [metadataItem valueForAttribute:NSMetadataUbiquitousItemIsDownloadedKey] 是什么?返回?
  • 这是问题的重点。没有生成缩略图可能是因为它们不在设备上,Apple 从不关心解释如何做到这一点,而且他们解释的方法不会下载任何东西。顺便说一句,从相机胶卷中下载所有图片似乎很愚蠢,浪费了大量的带宽,而你想要的只是一个 100x100 的缩略图。
  • 嗯 iCloud 的行为不是很透明。我会推荐以下方法: 1. 使用您的代码请求预生成的缩略图。在我的测试中,我经常在第二次调用它时得到结果。 2.如果还是没有得到重新生成的缩略图,使用 startDownloadingUbiquitousItemAtURL: 强制下载,然后使用我的代码生成缩略图。
【解决方案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% 有效的解决方案。其他人比这更糟糕。

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      这对我有用。它有点不同

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

      【讨论】:

      • 由于缩略图生成背景,可能需要多次调用
      猜你喜欢
      • 2011-06-28
      • 1970-01-01
      • 2014-07-02
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 2018-06-15
      • 2014-04-18
      相关资源
      最近更新 更多