如何获得iOS8 PhotoKit所需的图像大小?

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

[[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

你的(Unnati's)自己的答案是可行的,但是它会遗漏一些苹果在你的框架中为你提供的优化,让你的图像更快地显示出来。

你原来的代码是非常正确的,但是你包含了一个你可能不需要的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)); }]; 

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

快速响应低质量的图像

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

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

这意味着你的resultHandler块需要多次调用是安全的 – 你的代码中的代码块只是logging了大小,对于我的testing图像,我得到了两个日志消息,第一个是低质量的40×26像素图像,然后再用高质量的图像。 如果您打开iOS照片应用程序,则可能会在看起来很锐利之前非常简短地看到低质量的图像 – 这就是发生在这里的情况。

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

快速返回caching的高质量图像

为了快速提供最终的图像,框架将在最后调用resultHandler块时提供接近所需大小的图像(如果已经有一个图像)。 如果您使用的UIImageView设置了contentMode的方面填充或适合,这不会是一个问题,只需在图像请求中指定匹配的contentMode 。 例如,对我的testing图像来说,第二次调用我的resultHandler是一个1280×850的图像,比我所要求的要大,但是正确的放大。 但是,设置options.resizeMode = PHImageRequestOptionsResizeModeExact将阻止此行为,并强制框架调整图像的全新副本,而不是使用caching副本,这需要花费时间。

由于Photos框架不会裁剪图像(即使您提出要求,但这是一个错误;-)),即使使用PHImageRequestOptionsResizeModeExact选项,您也不一定会得到所请求的确切尺寸。 例如,如果您要求800×600的图像不是4:3的比例,则照片无法返回该尺寸的图像,只能得到尽可能接近的图像 – 在最新的图像上,像这样的请求会得到一个800×531的图像。 这意味着您需要能够处理不是您请求的确切大小的图像,所以您不妨利用框架中的优化,避免使用PHImageRequestOptionsResizeModeExact 。 再次从文档 :

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

(你有没有这个设置为PHImageRequestOptionsResizeModeFast在你原来的options对象,这是不包括在问题中?这可能是导致你的问题。)

图像版本

可以请求不同版本的图像,就像你自己用options.version = PHImageRequestOptionsVersionCurrent回答options.version = PHImageRequestOptionsVersionCurrent 。 不过这个不是必须的,因为默认是当前版本。

我能够使用下面的代码得到大小为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。