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

如何确定iOS设备上可用的最大PHAsset图像大小,其中“可用”是指设备上当前的设备,不需要从iCloud Photo Library进行任何networking下载?

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

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

在集合视图中,我使用PHCachingImageManager来caching (以及稍后请求 )具有186×186像素的targetSize的图像(由于视网膜缩放而使UICollectionViewCell尺寸加倍)。

这样做效果很好,滚动速度非常快,并且在填充图像的单元格中没有滞后。 检查返回的图像的大小,他们都是大约342×256像素。 这是在我的iPhone 6上启用了iCloud Photo Library并启用了“优化存储”,因此只有很小的缩略图才能存储在大多数图像的设备上。

然而,奇怪的是,如果我然后请求任何图像的全尺寸(或更大)的版本,使用PHImageRequestOptionsDeliveryMode.Opportunistic选项与PHCachingImageManagerPHImageManager.defaultManager() ,返回的第一个(低质量)图像是一个微小的60×45像素的邮票,看起来可怕的全屏幕,直到最终的全尺寸图像下载,以取代它。

显然,设备上已经有了更大的缩略图(342×256),因为它们刚刚显示在收集视图中! 那么为什么不把它们作为第一个“低质量”的形象归还,直到全尺寸下载? 只是为了确保342×256图像真的已经在设备上,我运行在飞行模式下的代码,所以没有networking访问发生。

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

我已经改变了我的代码,先制作一个256×256的请求,然后用PHImageRequestOptionsDeliveryMode.HighQualityFormat一个完整的请求(不会返回一个微小的中间图像),而且工作的很好。 这也是iOS的照片应用程序必须做什么,因为它显示相对高品质的缩略图,而下载完整的形象。

那么,在这样的背景下,我怎么知道PHAsset最大的设备图像尺寸是PHAsset ? 256×256是一个幻数,还是取决于iCloud Photo Library如何针对空间进行优化(基于库和可用设备存储的大小)?

当然,这似乎是一个照片框架没有返回当前可用的最大图像(当被问及尺寸大于目前的尺寸时)的错误,并且为了获得它的最大尺寸,您必须要求这个尺寸或更小,因为如果你要求更大,你会得到一个60×45的缩影! 离奇。

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

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

 let targetSize = PHImageManagerMaximumSize 

其实我不知道为什么苹果会返回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可能会使用这个类似的解决scheme来处理来自iCloud的图像。

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