Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS 8 PhotoKit. Get maximum-size image from iCloud Photo Sharing albums

How get access to the full-size images from iСloud? Every time I try to get this picture, I get image size 256x342. I not see progress too.

Code:

    PHFetchResult *result = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetIdentifier] options:nil];
    PHImageManager *manager = [PHImageManager defaultManager];
    [result enumerateObjectsUsingBlock:^(PHAsset *asset, NSUInteger idx, BOOL *stop) {

        PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
        options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
        options.synchronous = YES;
        options.networkAccessAllowed = YES;
        options.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
            NSLog(@"%f", progress);
        };

        [manager requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeDefault options:options resultHandler:^(UIImage *resultImage, NSDictionary *info)
         {
             UIImage *image = resultImage;
             NSLog(@"%@", NSStringFromCGSize(resultImage.size));
         }];
    }];

Until I click the picture in Photo app, this picture will be of poor quality. But as soon as I click on the picture, it downloaded on the device and will be full-size quality.

like image 675
Mikhail S Avatar asked Sep 15 '14 06:09

Mikhail S


People also ask

Is iCloud photo sharing full resolution?

You can also access your iCloud photos and videos in a web browser. The photos and videos you take are uploaded automatically and stored in their original format at full resolution. Any changes you make to your Photos collection on one device are reflected on your other devices too.

Are shared albums full resolution?

You can't. iCloud shared albums use low res copies. The high res original is on the phone of whoever took the photo. Have them send it to you via email or iMessage and it will be higher res.


2 Answers

I think the below should get the full resolution image data:

 [manager requestImageDataForAsset:asset 
                           options:options 
                     resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) 
             { 
                  UIImage *image = [UIImage imageWithData:imageData]; 

                  //...

             }];

The entire Photos Framework (PhotoKit) is covered in the WWDC video: https://developer.apple.com/videos/wwdc/2014/#511

Hope this helps.

Edit:

The resultHandler can be called twice. This is explained in the video I linked to at around 30:00. Could be that you are only getting the thumbnail and the full image will come with the second time its called.

like image 79
dloomb Avatar answered Nov 15 '22 15:11

dloomb


I'm having some of the same issues. It is either a bug or poor documentation. I've been able to get around the issue by specifying a requested size of 2000x2000. The problem with this is that I do get the full size image but sometimes it comes back marked as degraded so I keep waiting for a different image which never happens. This is what I do to get around those issues.

        self.selectedAsset = asset;

        self.collectionView.allowsSelection = NO;

        PHImageRequestOptions* options = [[[PHImageRequestOptions alloc] init] autorelease];
        options.synchronous = NO;
        options.version = PHImageRequestOptionsVersionCurrent;
        options.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
        options.resizeMode = PHImageRequestOptionsResizeModeNone;
        options.networkAccessAllowed = YES;
        options.progressHandler =  ^(double progress,NSError *error,BOOL* stop, NSDictionary* dict) {
            NSLog(@"progress %lf",progress);  //never gets called
        };

        [self.delegate choosePhotoCollectionVCIsGettingPhoto:YES];  //show activity indicator
        __block BOOL isStillLookingForPhoto = YES;

        currentImageRequestId = [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:CGSizeMake(2000, 2000) contentMode:PHImageContentModeAspectFill options:options resultHandler:^(UIImage *result, NSDictionary *info) {
            NSLog(@"result size:%@",NSStringFromCGSize(result.size));

            BOOL isRealDealForSure = NO;
            NSNumber* n = info[@"PHImageResultIsPlaceholderKey"]; //undocumented key so I don't count on it
            if (n != nil && [n boolValue] == NO){
                isRealDealForSure = YES;
            }

            if([info[PHImageResultIsInCloudKey] boolValue]){
                NSLog(@"image is in the cloud"); //never seen this. (because I allowed network access)
            }
            else if([info[PHImageResultIsDegradedKey] boolValue] && !isRealDealForSure){
                    //do something with the small image...but keep waiting
                [self.delegate choosePhotoCollectionVCPreviewSmallPhoto:result];
                self.collectionView.allowsSelection = YES;
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ //random time of 3 seconds to get the full resolution in case the degraded key is lying to me. The user can move on but we will keep waiting.
                    if(isStillLookingForPhoto){
                        self.selectedImage = result;
                        [self.delegate choosePhotoCollectionVCPreviewFullPhoto:self.selectedImage]; //remove activity indicator and let the user move on
                    }
                });
            }
            else {
                    //do something with the full result and get rid of activity indicator.
                if(asset == self.selectedAsset){
                    isStillLookingForPhoto = NO;
                    self.selectedImage = result;
                    [self.delegate choosePhotoCollectionVCPreviewFullPhoto:self.selectedImage];
                    self.collectionView.allowsSelection = YES;
                }
                else {
                    NSLog(@"ignored asset because another was pressed");
                }
            }
        }];
like image 31
spenceps Avatar answered Nov 15 '22 13:11

spenceps