您(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 通过其框架提供的所有优化。这是您得到的解释:
以低质量图像快速响应
该框架将多次调用您的结果处理程序以提高图像质量,从而允许您在用户等待最终图像时向他们显示一些内容。从文档中:
照片可能会多次调用您的结果处理程序块。照片首先调用该块以提供适合临时显示的低质量图像,同时准备高质量图像。(如果低质量图像数据立即可用,则第一次调用可能会在方法返回之前发生。)当高质量图像准备好时,Photos 会再次调用您的结果处理程序以提供它。
这意味着您的resultHandler
块需要安全地多次调用 - 代码中的块只是记录大小,对于我的测试图像,我收到两条日志消息,第一条是低质量 40x26 像素图像,然后再次以高质量的图像。如果您打开 iOS 照片应用程序,您可以在它们看起来锐化之前非常短暂地看到低质量图像 - 这就是这里发生的事情。
使用options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat
可以防止这种行为,并且您resultHandler
只会在最终图像中调用一次,因此我建议不要设置此选项,除非您无法设计可以多次调用的处理程序块(在您的真实代码中)。
快速返回缓存的高质量图像
为了快速提供最终图像,框架将在对块的最终调用中提供接近请求大小的图像resultHandler
,如果它已经缓存了一个。如果您使用的是UIImageView
具有宽高比填充或适合的集合contentMode
,这不会有问题,只需contentMode
在您的图像请求中指定匹配即可。例如,针对我的测试图像,对我的第二次调用resultHandler
是使用 1280x850 的图像,比我要求的大,但正确的球场。但是,设置options.resizeMode = PHImageRequestOptionsResizeModeExact
将阻止这种行为并强制框架调整图像的新副本而不是使用缓存副本,这需要时间。
由于 Photos 框架不裁剪图像(即使您要求它,但这是一个错误 ;-)),即使使用该PHImageRequestOptionsResizeModeExact
选项,您也不一定会获得您请求的确切尺寸。例如,如果您为不是 4:3 比例的图像请求 800x600,则照片无法返回该尺寸的图像,它只会尽可能接近 - 在我的最新图像上,这样的请求得到800x531 的图像。这意味着您需要能够处理不符合您要求的确切尺寸的图像,因此您不妨利用框架中的优化并避免使用PHImageRequestOptionsResizeModeExact
. 再次从文档中:
调整大小以完全匹配目标大小比使用快速调整大小选项效率低。
(您是否PHImageRequestOptionsResizeModeFast
在原始options
对象中设置了此设置,但问题中未包含该设置?这可能导致了您的问题。)
图像版本
可以请求图像的不同版本,就像您在自我回答中所做的那样options.version = PHImageRequestOptionsVersionCurrent
。但是,这不是必需的,因为默认值是当前版本。