确定iOS设备上可用的最大PHAsset图像大小

时间:2015-09-01 23:43:26

标签: ios photokit phasset icloud-photo-library

如何确定iOS设备上可用的最大PHAsset图像尺寸,其中“可用”我的意思是当前在设备上,不需要从iCloud照片库进行任何网络下载?

我一直在开发一个应用程序,其中缩略图的集合显示在UICollectionView(很像照片应用程序),然后用户可以选择图像以查看其全尺寸。如有必要,可从iCloud下载完整大小的图像。但是,我希望向用户显示最大可能版本的图像,直到完整尺寸可用。

照片框架的工作方式相当奇怪:

在集合视图中,我使用PHCachingImageManagercache(以及后来的request)图像,其中targetSize为186x186像素(是{{1}的两倍由于视网膜缩放而导致的尺寸)。

效果非常好,滚动速度非常快,并且在用图像填充单元格时没有延迟。检查返回图像的大小,它们大约是342x256像素。这是在我的iPhone 6上启用了iCloud Photo Library并启用了“优化存储”,因此大多数图像只能在设备上存储小的缩略图。

然而,奇怪的是,如果我随后使用PHImageRequestOptionsDeliveryMode.Opportunistic选项使用UICollectionViewCellPHCachingImageManager请求任何图片的完整尺寸(或更大)版本,返回的第一个(低质量)图像是一个60x45像素的小邮票,在全屏幕上看起来很糟糕,直到最终下载全尺寸图像来替换它。

显然,设备上已经有 更大的缩略图(342x256),因为它们只显示在集合视图中!那么为什么地狱不会将它们作为第一个“低质量”图像返回,直到下载完整尺寸?为了确保342x256图像确实已经在设备上,我在飞行模式下运行代码,因此无法进行网络访问。

我发现如果我要求任何尺寸高达256x256,我会得到342x256图像。一旦我变大(甚至1像素),它将首先返回60x45图像,然后尝试下载完整尺寸的图像。

我已经更改了我的代码以首先发出256x256请求,然后是PHImageManager.defaultManager()的完整大小请求(它不会返回微小的中间图像),并且效果很好。它也是iOS Photos应用程序必须要做的,因为它在下载完整图像时显示相对高质量的缩略图。

因此,在此背景下,我如何知道PHImageRequestOptionsDeliveryMode.HighQualityFormat设备图像大小的最大值? 256x256是一个神奇的数字,还是取决于iCloud Photo Library如何针对空间进行优化(基于库的大小和可用的设备存储)?

当然,似乎是一个错误,照片框架没有返回当前可用的最大图像(当要求的尺寸大于目前的尺寸时),并且为了获得它拥有的最大尺寸,你必须要求这个尺寸或更小,因为如果你要求更大,你将得到一个60x45微型!奇异。

更新:提交给Apple的错误报告:https://openradar.appspot.com/25181601
演示错误的示例项目:https://github.com/mluisbrown/PhotoKitBug

3 个答案:

答案 0 :(得分:1)

使用问题中发布的示例项目,我能够在模拟器中重现该问题,但是当我做出以下更改时,我只会收到最大的图像:

let targetSize = PHImageManagerMaximumSize

答案 1 :(得分:0)

实际上,我不知道Apple为什么会使用PHImageResultIsDegradedKey = 1返回降级的45 * 60图像。对我来说,我只是首先使用deliveryMode PHImageRequestOptionsDeliveryModeHighQualityFormat请求256 * 256图像,然后我使用其他PHImageRequestOptions来请求如下所示的全尺寸图像:

PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.networkAccessAllowed = YES;
options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
options.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info){
// code to update the iCloud download progress
});

[[PHImageManager defaultManager] requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeAspectFit options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
// code to update UIImageView or something else.
});

我认为,Instagram可能会使用这种类似的解决方案来处理来自iCloud的图像。

答案 2 :(得分:-2)

[imageManager requestImageForAsset:asset
              targetSize: PHImageManagerMaximumSize
              contentMode:PHImageContentModeAspectFill
              options:nil
resultHandler:^(UIImage *result, NSDictionary *info)
{
    result;
}];
相关问题