Determine the largest PHASset image size available on your iOS device

How can I determine the largest PHAsset image size that is available on an iOS device, where “affordable” do I mean currently on the device without requiring a network download from iCloud Photo Library?

I am developing an application in which a collection of thumbnails is displayed in a UICollectionView (just like the Photos application), and then the user can select an image to see it in full size. Full size image is downloaded from iCloud, if necessary. However, I want to show the user the largest possible version of the image until the full size is available.

The way of working with photos is rather strange:

In the collection view, I use PHCachingImageManager in cache (and later request ) with targetSize of 186x186 pixels (half the size of UICollectionViewCell due to retina scaling).

This works very well, with very fast scrolling and no delay when filling cells with images. Checking the size of the returned images, they are all approximately 342x256 pixels. The fact that on my iPhone 6 with iCloud Photo Library is turned on and "Optimize storage" is turned on, so for most images only small thumbnails are stored on the device.

However, the odd part is that if I then request the full (or much larger) version of any image, either using PHCachingImageManager or PHImageManager.defaultManager() using PHImageRequestOptionsDeliveryMode.Opportunistic , the first (low quality) image that returns represents it’s a tiny 60x45-pixel postage stamp that looks horrible on the whole screen until it finally loads a full-size image to replace it.

It is clear that the device already has large thumbnails (342x256), since they were shown only as a collection! So why the hell doesn't he return them as the first “low quality” image until the full size is downloaded? To make sure that the 342x256 images really were on the device, I ran the code in airplane mode so that there was no access to the network.

I found that if I requested a size up to 256x256, I would get 342x256 images returned. As soon as I got bigger (even 1 pixel), it will first return me 60x45 images, and then try to load a full-size image.

I modified my code to first execute a 256x256 request, and then a full size request with PHImageRequestOptionsDeliveryMode.HighQualityFormat (which does not return a small intermediate image), and this works great. This is also what the iOS Photos app should do, as it displays relatively high quality thumbnails when loading a full image.

So, with this background, how do you know what is the largest device image size for PHAsset ? Is a 256x256 magic number or depends on how iCloud Photo Library optimizes space (based on library size and available device storage)?

Of course, it seems that the error is that the Photos Framework does not return the largest image currently available (when asked about a size that is larger than at the moment), and in order to get the largest size it has, you must ask about this size or less, because if you ask for more, you will get a 60x45 thumbnail! Bizarre

UPDATE: Bug Report submitted by Apple: https://openradar.appspot.com/25181601
An example project showing an error: https://github.com/mluisbrown/PhotoKitBug

+50
ios photokit phasset icloud-photo-library
Sep 01 '15 at 23:43
source share
3 answers

Using the sample project posted in the question, I was able to reproduce the problem in the simulator, but when I made the following change, I would get only the largest image:

 let targetSize = PHImageManagerMaximumSize 
+1
Apr 08 '16 at 17:56 on
source share

Actually, I don’t know the reason Apple will return a 45 * 60 degraded image with PHImageResultIsDegradedKey = 1. For me, I just request a 256 * 256 image with the delivery methodMode PHImageRequestOptionsDeliveryModeHighQualityFormat, then I use other PHImageRequestOptions to request a full size image, as shown below:

 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. }); 

And I think Instagram can use this similar solution to process images from iCloud.

0
Nov 01 '16 at 2:11
source share
 [imageManager requestImageForAsset:asset targetSize: PHImageManagerMaximumSize contentMode:PHImageContentModeAspectFill options:nil resultHandler:^(UIImage *result, NSDictionary *info) { result; }]; 
-one
Apr 16 '16 at 9:41
source share



All Articles