【问题标题】:How to get requested image size for iOS8 PhotoKit?如何为 iOS8 PhotoKit 获取请求的图像大小?
【发布时间】:2014-11-14 13:23:53
【问题描述】:

我正在使用下面的代码来获取图像:

[[PHImageManager defaultManager] requestImageForAsset:asset 
targetSize:CGSizeMake(800, 600) 
contentMode:PHImageContentModeAspectFill 
options:options 
resultHandler:^(UIImage *result, NSDictionary *info) {
    NSLog(@"size:%@",NSStringFromCGSize(result.size));                
}];

我请求的图像尺寸为 800 x 600,但我得到的图像尺寸为 45 x 60,质量非常差。

如何使用PhotoKit 获取请求的图像大小?

【问题讨论】:

  • 源图片的分辨率是多少?

标签: ios iphone image ios8 photokit


【解决方案1】:

您(Unnati 的)自我回答会起作用,但是它错过了 Apple 在其框架中为您提供的一些优化,这些优化可以让您更快地显示图像。

您的原始代码非常正确,但是您包含了一个您可能不需要的 options 对象,如果您在其上错误地设置了 resizeMode,可能会导致您出现问题。这是应该为您工作的代码,我刚刚删除了您的选项对象。

[[PHImageManager defaultManager]
 requestImageForAsset:(PHAsset *)asset
 targetSize:CGSizeMake(800, 600)
 contentMode:PHImageContentModeAspectFit
 options:nil
 resultHandler:^(UIImage *result, NSDictionary *info) {
     NSLog(@"Image size:%@",NSStringFromCGSize(result.size));
 }];

这应该更简单,并为您提供 Apple 免费提供的所有优化框架。以下是您得到的解释:

以低质量图像快速响应

该框架将多次调用您的结果处理程序以提高图像质量,从而允许您在用户等待最终图像时向他们显示一些内容。来自the documentation

照片可能会多次调用您的结果处理程序块。照片首先调用该块以提供适合临时显示的低质量图像,同时准备高质量图像。 (如果低质量图像数据立即可用,则第一次调用可能会在方法返回之前发生。)当高质量图像准备好时,Photos 会再次调用您的结果处理程序以提供它。

这意味着您的 resultHandler 块需要安全地多次调用 - 您代码中的块只是记录大小,对于我的测试图像,我收到两条日志消息,第一条质量低40x26 像素图像,然后再次使用高质量图像。如果您打开 iOS 照片应用程序,您可以在图像锐化之前非常短暂地看到低质量图像 - 这就是这里发生的情况。

使用options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat 可以防止这种行为,并且您的resultHandler 只会在最终图像中被调用一次,所以我建议不要设置此选项,除非您无法设计一个处理程序块(在您的真实代码中)可以多次调用。

快速返回缓存的高质量图片

为了快速提供最终图像,框架将在对resultHandler 块的最终调用中提供接近请求大小的图像,如果它已经缓存了一个。如果您使用的UIImageView 设置具有宽高比填充或适合的contentMode,这不会有问题,只需在图像请求中指定匹配的contentMode。例如,针对我的测试图像,对我的resultHandler 的第二次调用是使用 1280x850 的图像,比我要求的要大,但是是正确的。但是,设置options.resizeMode = PHImageRequestOptionsResizeModeExact 将阻止这种行为,并强制框架调整图像的新副本而不是使用缓存副本,这需要时间。

由于照片框架不裁剪图像(即使您要求它,但这是一个错误 ;-)),即使使用 PHImageRequestOptionsResizeModeExact 选项,您也不一定会得到您请求的确切尺寸。例如,如果您为不是 4:3 比例的图像请求 800x600,则照片无法返回该尺寸的图像,它只会尽可能接近 - 在我的最新图像上,这样的请求得到800x531 的图像。这意味着您需要能够处理不符合您要求的确切尺寸的图像,因此您不妨利用框架中的优化并避免使用PHImageRequestOptionsResizeModeExact。再次来自the documentation

调整大小以完全匹配目标大小比使用快速调整大小选项效率低。

(您是否在原始options 对象中将此设置为PHImageRequestOptionsResizeModeFast,而这未包含在问题中?这可能导致了您的问题。)

图像版本

您可以请求不同版本的图像,就像您在options.version = PHImageRequestOptionsVersionCurrent 的自我回答中所做的那样。但是,这不是必需的,因为默认是当前版本。

【讨论】:

  • 非常彻底和有益的回应。谢谢。
【解决方案2】:

我能够使用以下代码获得尺寸为 800*600 的图像:

PHImageRequestOptions* options = [[[PHImageRequestOptions alloc] init] autorelease];
options.version = PHImageRequestOptionsVersionCurrent;
options.deliveryMode =  PHImageRequestOptionsDeliveryModeHighQualityFormat;
options.resizeMode = PHImageRequestOptionsResizeModeExact;

[PHImageManager defaultManager]
requestImageForAsset:(PHAsset *)asset
targetSize:CGSizeMake(800, 600)
contentMode:PHImageContentModeAspectFit
options:options
resultHandler:^(UIImage *result, NSDictionary *info) {
   NSLog(@"Image size:%@",NSStringFromCGSize(result.size));
}];

如果你想获得完整尺寸的图像,你可以使用PHImageManagerMaximumSize 作为 targetSize。

【讨论】:

  • 这可能会有风险,具体取决于您对图像的处理方式 - iPhone 6 可以捕捉 43 兆像素的全景图 - 您是否有足够的内存在您的应用程序中处理这些问题?你真的需要全尺寸,还是 800*600 更好?
  • 但你并不总是得到你想要的。在这里查看我的答案:stackoverflow.com/a/27174448/569604
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-27
  • 1970-01-01
  • 2010-10-06
相关资源
最近更新 更多