Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/109.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
确定iOS设备上可用的最大PHAsset映像大小_Ios_Photokit_Phasset_Icloud Photo Library - Fatal编程技术网

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

确定iOS设备上可用的最大PHAsset映像大小,ios,photokit,phasset,icloud-photo-library,Ios,Photokit,Phasset,Icloud Photo Library,如何确定iOS设备上可用的最大PHAsset图像大小,其中“可用”指的是设备上当前的图像大小,不需要从iCloud照片库进行任何网络下载 我一直在开发一个应用程序,其中一组缩略图显示在UICollectionView(与照片应用程序非常相似)中,然后用户可以选择一张图片来查看其全尺寸。如有必要,可从iCloud下载全尺寸图像。但是,我希望向用户显示尽可能大的图像版本,直到完整尺寸可用为止 照片框架的工作方式相当奇怪: 在集合视图中,我使用PHCachingImageManagerto(及更高版本

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

我一直在开发一个应用程序,其中一组缩略图显示在
UICollectionView
(与照片应用程序非常相似)中,然后用户可以选择一张图片来查看其全尺寸。如有必要,可从iCloud下载全尺寸图像。但是,我希望向用户显示尽可能大的图像版本,直到完整尺寸可用为止

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

在集合视图中,我使用
PHCachingImageManager
to(及更高版本)图像,其
targetSize
为186x186像素(由于视网膜缩放,因此是
UICollectionViewCell
尺寸的两倍)

这非常有效,滚动速度非常快,在用图像填充单元格时没有延迟。检查返回图像的大小,它们都大约为342x256像素。这是在我的iPhone 6上,启用了iCloud照片库并启用了“优化存储”,所以对于大多数图像,设备上只存储了小的缩略图

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

显然,设备上已经有了更大的缩略图(342x256),因为它们刚刚显示在“收藏”视图中!那么,在下载完整尺寸之前,它为什么不将它们作为第一张“低质量”图像返回呢??为了确保342x256图像确实已经在设备上,我在飞行模式下运行了代码,因此没有发生网络访问

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

我已经更改了代码,先发出256x256请求,然后是带有
PhimageRequestOptions DeliveryMode.HighQualityFormat
(不会返回微小的中间图像)的全尺寸请求,效果很好。这也是iOS照片应用程序必须要做的,因为它在下载完整图像时会显示相对高质量的缩略图

那么,在这样的背景下,我如何知道
PHAsset
的最大设备图像大小是多少呢?256x256是一个神奇的数字,还是取决于iCloud照片库如何优化空间(基于库的大小和可用设备存储)

显然,Photos Framework没有返回当前可用的最大图像(当要求返回比当前大小更大的图像时)似乎是一个错误,要获得最大的图像,您必须要求该大小或更小的图像,因为如果您要求更大的图像,您将获得60x45的缩影!奇怪

更新:提交给苹果的错误报告:

演示错误的示例项目:

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

let targetSize = PHImageManagerMaximumSize

事实上,我不知道苹果为什么会返回PHImageResultIsDegradedKey=1的降级45*60图像。对于我来说,我首先使用deliveryMode PHImageRequestOptions DeliveryModeHighQualityFormat请求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的图像。

在获取缩略图时,您是使用PHImageManager.defaultManager()执行同步还是异步请求?@ArunAmmannaya我使用的是
phcachingimanager
来获取缩略图,并且请求是异步的。然后,假设您对请求的图像使用不同大小的单个图像获得多个回调。回拨电话有多少次?@ArunAmmannaya是的,我很清楚这一点,我在问题中提到了这一点。不管怎样,如果设备上已经有342x256个图像,返回60x45个图像是没有意义的,尤其是如果您实际请求了更大的尺寸。正如我在问题中所说,请求最大256x256将返回可用的最大缩略图(至少在我的情况下是这样),但请求257x257(或更大)将突然使您只能获得60x45的缩略图。我遇到了类似的问题。小于某个大小请求的图像将返回nil,大于该大小的图像将返回完整大小的图像。我尝试了networkAccessAllowed=true,获得的图像几乎符合要求。对targetSize使用
PHImageManagerMaximumSize
意味着获得完整分辨率图像,如果不可用,则什么也得不到。在模拟器上,全分辨率图像始终可用。但是,在设备上,通常无法获得iCloud照片库的完整分辨率图像。在示例项目中使用
PHImageManagerMaximumSize
将根本不会返回任何图像,因为它使用的是
networkAccessAllowed=false
选项。所以这恐怕没有什么帮助:-(@mluisbrown循环回到这个问题。这里的协议是什么?我应该删除这个答案,还是保留它,这样其他人就不会发布相同的答案(显然这不起作用)?马克,我想你应该留下答案。这是一个有效的建议。当我看到它时,我跑回我的Mac思考“这真的有那么明显吗?”事实上值得投一票:)如果你费心读马克·沃森的答案,你就会知道为什么这不起作用(读我对这个答案的评论)。
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.
});