如何获取iOS8 PhotoKit所需的图像尺寸?

Unn*_*ati 12 iphone image ios ios8 photokit

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

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

我要求的图像尺寸为800 x 600,但我的图像尺寸为45 x 60,质量非常差.

如何使用PhotoKit?获取所需的图像尺寸?

Jos*_*ald 18

你的(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));
 }];
Run Code Online (Sandbox Code Playgroud)

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

快速响应低质量图像

框架将使用不断提高的图像质量多次调用结果处理程序,允许您在等待最终图像时向用户显示内容.从文档:

照片可能会多次调用您的结果处理程序块.照片首先调用块以提供适合于在准备高质量图像时临时显示的低质量图像.(如果立即可以获得低质量图像数据,则可以在方法返回之前进行第一次调用.)当高质量图像准备就绪时,Photos会再次调用结果处理程序来提供它.

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

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

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

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

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

调整大小以精确匹配目标大小的效率低于使用快速调整大小选项的效率.

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

图像版本

可以请求不同版本的图像,就像您自己回答一样options.version = PHImageRequestOptionsVersionCurrent.但是,这不是必需的,因为默认值是当前版本.


Unn*_*ati 13

我可以使用以下代码获得大小为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));
}];
Run Code Online (Sandbox Code Playgroud)

如果你想获得全尺寸图像,你可以使用PHImageManagerMaximumSizetargetSize.