如何确定PHAssetiOS设备上可用的最大图像大小,其中"可用"我的意思是当前在设备上,不需要从iCloud照片库进行任何网络下载?
我一直在开发一个应用程序,其中一组缩略图显示在UICollectionView(很像照片应用程序),然后用户可以选择一个图像来查看它的全尺寸.如有必要,可从iCloud下载完整大小的图像.但是,我希望向用户显示图像的最大版本,直到完整大小可用.
Photos Framework的工作方式相当奇怪:
在集合视图中,我使用a PHCachingImageManager来缓存(以及稍后请求)具有targetSize186x186像素的图像(UICollectionViewCell由于视网膜缩放而使尺寸加倍).
这非常有效,滚动非常快,并且在用图像填充单元格时没有延迟.检查返回图像的大小,它们大约是342x256像素.这是在我的iPhone 6上启用了iCloud Photo Library并启用了"优化存储",因此大多数图像只能在设备上存储小的缩略图.
然而,奇怪的是,如果我然后请求任何图像的完整尺寸(或更大)版本,使用PHCachingImageManager或PHImageManager.defaultManager()使用该PHImageRequestOptionsDeliveryMode.Opportunistic选项,返回的第一个(低质量)图像是一个小的60x45像素邮票,看起来在全屏幕上可怕,直到最终下载完整尺寸的图像来替换它.
显然,在设备上更大的缩略图(342x256)已经,因为他们是在集合视图只是显示!那么为什么地狱不会将它们作为第一个"低质量"图像返回,直到下载完整尺寸?为了确保342x256图像确实已经在设备上,我在飞行模式下运行代码,因此没有发生网络访问.
我发现如果我要求任何大小高达256x256我会得到342x256图像返回.一旦我变大(甚至1个像素),它将首先返回60x45图像然后尝试下载全尺寸图像.
我已经更改了我的代码以首先发出256x256请求,然后是一个完整大小的请求PHImageRequestOptionsDeliveryMode.HighQualityFormat(它不会返回一个微小的中间图像),并且工作得非常好.它也是iOS Photos应用程序必须要做的,因为它在下载完整图像时显示相对高质量的缩略图.
那么,在这样的背景下,我怎么知道设备图像尺寸最大的是PHAsset什么?256x256是一个神奇的数字,还是取决于iCloud Photo Library如何优化空间(基于库的大小和可用的设备存储)?
当然,似乎是一个错误,照片框架没有返回当前可用的最大图像(当要求的尺寸大于目前的尺寸),并且要获得它拥有的最大尺寸,你必须要求这个尺寸或更小,因为如果你要求更大,你将获得60x45的缩影!离奇.
更新:提交给Apple的错误报告:https://openradar.appspot.com/25181601
演示该错误的示例项目:https://github.com/mluisbrown/PhotoKitBug
Apple将在iOS 9/iPhone 6s中推出Live Photo.文件格式在哪里记录?
文档说:
PHImageResultIsInCloudKey:一个布尔值,指示照片资产数据是存储在本地设备上还是必须从iCloud下载.(NSNumber)如果是,则不提供图像,因为必须从iCloud下载资产数据.要下载数据,请提交另一个请求,并为networkAccessAllowed选项指定YES.
但是当资产存储在iCloud照片库中时,此键始终为YES,即使已将其完全下载到设备中(在我的应用程序中下载,也在照片应用程序中打开).
如果图像不可用,我想让用户可以下载它(但不要自动执行,至少在没有Wifi的情况下不这样做).
那么如何确定图像是否需要下载?
更奇怪的是:当我的结果块
requestImageForAsset:targetSize:contentMode:options:resultHandler:
被调用需要下载的图像时,我会在传递较小且降级的版本之后使用requestedImage == nil进行最后一次调用.
在这种情况下降级为NO,即使我没有图像,仍然必须从iCloud下载图像,因为到目前为止,只有照片应用程序中的一个小缩略图在本地可用.
我在具有不同iOS 8版本(8.1.x,8.2 beta,8.3 beta)的iPhone和iPad上进行了测试,行为总是相同的.
在Photos应用程序中打开图像后,结果处理程序的最后一次调用具有完整大小的图像,但PHImageResultIsInCloudKey仍为YES.
这是我如何请求图像的一些代码:
PHImageRequestOptions *options = [[PHImageRequestOptions alloc]init];
options.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
options.networkAccessAllowed = NO;
[self.imageManager requestImageForAsset:asset targetSize:size contentMode:PHImageContentModeAspectFill options:options resultHandler:^(UIImage *requestedImage, NSDictionary *info) {
// Checking for requestedImage and the info keys here
// When a full sized image was loaded, the result of PHImageResultIsInCloudKey is still YES
// When a full sized image couldn't be loaded cause it's in the cloud, isDegraded is NO and …Run Code Online (Sandbox Code Playgroud) 你可以偷偷地使用未记录的 PHAsset.ALAssetURL财产† ,但我正在寻找记录的东西.
†在Objective-C中,这将有所帮助
@interface PHAsset (Sneaky)
@property (nonatomic, readonly) NSURL *ALAssetURL;
@end
Run Code Online (Sandbox Code Playgroud) 在iOS 8的Photos.framework中,我正在尝试将UIImage保存到用户的照片库,就像在Safari中长按图像并选择"保存图像"一样.在iOS 7中,这只需要调用ALAssetLibrary writeImageToSavedPhotosAlbum:metadata:completionBlock.
对于iOS 8,我们需要选择一个资产集合来添加PHAsset,但我无法弄清楚哪个PHAssetCollection最接近只保存到用户的"相机滚动"(即使在iOS中没有,真的, 8)
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *newAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
newAssetRequest.creationDate = time;
newAssetRequest.location = location;
PHObjectPlaceholder *placeholderAsset = newAssetRequest.placeholderForCreatedAsset;
PHAssetCollectionChangeRequest *addAssetRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:WHICH_ASSET_COLLECTION];
addAssetRequest addAssets:@[placeholderAsset];
} completionHandler:^(BOOL success, NSError *error) {
NSLog(@"Success: %d", success);
}];
Run Code Online (Sandbox Code Playgroud)
我尝试访问"最近添加"的智能相册,但不允许添加新内容.
我正在使用Photos框架来获取iOS8中的专辑列表.我能够使用它
PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
Run Code Online (Sandbox Code Playgroud)
这给了我所有智能相册的列表,包括视频.如何过滤此列表中的视频.我只需要图像.
帮助将不胜感激.谢谢.
CollectionViewController.m第439行__50- [CollectionViewController photoLibraryDidChange:] _ block_invoke
致命异常:NSInternalInconsistencyException尝试删除并重新加载相同的索引路径({length = 2,path = 0 - 26007})
- (void)photoLibraryDidChange:(PHChange *)changeInstance
{
// Call might come on any background queue. Re-dispatch to the main queue to handle it.
dispatch_async(dispatch_get_main_queue(), ^{
// check if there are changes to the assets (insertions, deletions, updates)
PHFetchResultChangeDetails *collectionChanges = [changeInstance changeDetailsForFetchResult:self.assetsFetchResults];
if (collectionChanges) {
// get the new fetch result
self.assetsFetchResults = [collectionChanges fetchResultAfterChanges];
UICollectionView *collectionView = self.collectionView;
if (![collectionChanges hasIncrementalChanges] || [collectionChanges hasMoves]) {
// we need to reload …Run Code Online (Sandbox Code Playgroud) 我的应用程序允许用户使用Photos框架编辑照片.我看到一些崩溃报告,并且在生成输出图像时出现崩溃,但我不确定问题出在哪里.此崩溃发生在多个硬件设备和多个版本的iOS 9上,包括最新的9.1.我的应用程序最后一次调用是CGImageDestinationFinalize为了创建编辑过的图像NSData.崩溃报告显示在崩溃发生之前,CoreImage空间中的调用继续显示在GLTextureManager中.
这可能是内存不足的问题吗?你看到了这个问题吗?怎么解决这个问题?
从相关的代码PhotoEditor.swift,里面的功能fullImageOutput这与所谓的editSingleAsset它在后台队列运行QOS_CLASS_UTILITY:
let outputPhoto = //the generated CIImage that is the edited photo to be saved to disk
let dataRef = CFDataCreateMutable(nil, 0)
if let destination = CGImageDestinationCreateWithData(dataRef, "public.jpeg", 1, nil) {
struct ContextStruct {
static var ciContext: CIContext? = nil
}
if ContextStruct.ciContext == nil {
let eaglContext = EAGLContext(API: .OpenGLES2)
ContextStruct.ciContext = CIContext(EAGLContext: eaglContext)
}
let cgImage = ContextStruct.ciContext!.createCGImage(outputPhoto, fromRect: outputPhoto.extent)
CGImageDestinationAddImage(destination, cgImage, nil) …Run Code Online (Sandbox Code Playgroud) 在iOS 8中,使用新的PhotoKit,创建新图像的方法是-[PHPhotoLibrary performChanges:completionHandler]这样:
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *changeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
// TODO set metadata?
} completionHandler:^(BOOL success, NSError *error) {
if(success)
{
// do stuff
}
}];
Run Code Online (Sandbox Code Playgroud)
但是,我找不到有关如何在图像上设置元数据的任何文档.
在旧的ALAssetLibrary中(它仍然有效,并且可能仍然是'正确的'前进方式),您只需使用-[ALAssetLibrary writePhotoToSavedPhotosAlbum:metadata:completionBlock:],它允许您传入元数据字典.
PhotoKit中是否有等效的方法?
我使用下面的代码来获取图像:
[[PHImageManager defaultManager] requestImageForAsset:asset
targetSize:CGSizeMake(800, 600)
contentMode:PHImageContentModeAspectFill
options:options
resultHandler:^(UIImage *result, NSDictionary *info) {
NSLog(@"size:%@",NSStringFromCGSize(result.size));
}];
Run Code Online (Sandbox Code Playgroud)
我要求的图像尺寸为800 x 600,但我的图像尺寸为45 x 60,质量非常差.
如何使用PhotoKit?获取所需的图像尺寸?
photokit ×10
ios ×8
ios8 ×5
phasset ×4
objective-c ×3
alasset ×1
core-image ×1
crash ×1
exif ×1
image ×1
ios9 ×1
iphone ×1
metadata ×1
phlivephoto ×1
photolibrary ×1