如何确定iOS设备上可用的最大PHAsset
图像尺寸,其中“可用”我的意思是当前在设备上,不需要从iCloud照片库进行任何网络下载?
我一直在开发一个应用程序,其中缩略图的集合显示在UICollectionView
(很像照片应用程序),然后用户可以选择图像以查看其全尺寸。如有必要,可从iCloud下载完整大小的图像。但是,我希望向用户显示最大可能版本的图像,直到完整尺寸可用。
照片框架的工作方式相当奇怪:
在集合视图中,我使用PHCachingImageManager
到cache(以及后来的request)图像,其中targetSize
为186x186像素(是{{1}的两倍由于视网膜缩放而导致的尺寸)。
效果非常好,滚动速度非常快,并且在用图像填充单元格时没有延迟。检查返回图像的大小,它们大约是342x256像素。这是在我的iPhone 6上启用了iCloud Photo Library并启用了“优化存储”,因此大多数图像只能在设备上存储小的缩略图。
然而,奇怪的是,如果我随后使用PHImageRequestOptionsDeliveryMode.Opportunistic
选项使用UICollectionViewCell
或PHCachingImageManager
请求任何图片的完整尺寸(或更大)版本,返回的第一个(低质量)图像是一个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
答案 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;
}];