web-dev-qa-db-fra.com

photoKit iOS 8. Obtenez une image de taille maximale à partir d'albums iCloud Photo Sharing

Comment accéder aux images en taille réelle depuis iСloud? Chaque fois que j'essaie d'obtenir cette image, la taille de l'image est 256x342. Je ne vois pas de progrès aussi. 

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

Jusqu'à ce que je clique sur la photo dans l'application Photo, cette photo sera de mauvaise qualité. Mais dès que je clique sur la photo, celle-ci se télécharge sur l'appareil et sera de taille normale.

15
Mikhail S

Je pense que ci-dessous devrait obtenir les données d'image en pleine résolution:

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

                  //...

             }];

Le cadre photo complet (PhotoKit) est traité dans la vidéo WWDC: https://developer.Apple.com/videos/wwdc/2014/#511

J'espère que cela t'aides.

Modifier:

Le resultHandler peut être appelé deux fois. Ceci est expliqué dans la vidéo vers 30h00 que j'ai liée. Peut-être que vous n'obtenez que la vignette et que l'image complète apparaîtra à la deuxième appel.

14
dloomb

J'ai certains des mêmes problèmes. C'est soit un bug, soit une mauvaise documentation. J'ai pu contourner le problème en spécifiant une taille demandée de 2000x2000. Le problème, c’est que j’obtiens l’image en taille réelle mais que parfois elle revient marquée comme dégradée, je continue donc à attendre une autre image, ce qui n’arrive jamais. C'est ce que je fais pour contourner ces problèmes.

        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");
                }
            }
        }];
2

Pour obtenir l’image en taille réelle, vous devez vérifier la liste d’informations. Je l’ai utilisé pour vérifier si le résultat renvoyé correspond à l’image complète ou à une version dégradée.

if ([[info valueForKey:@"PHImageResultIsDegradedKey"]integerValue]==0){
    // Do something with the FULL SIZED image
} else {
    // Do something with the regraded image
}

ou vous pouvez l'utiliser pour vérifier si vous avez obtenu ce que vous avez demandé.

if ([[info valueForKey:@"PHImageResultWantedImageFormatKey"]integerValue]==[[info valueForKey:@"PHImageResultDeliveredImageFormatKey"]integerValue]){
    // Do something with the FULL SIZED image
} else {
    // Do something with the regraded image
}

Il existe un certain nombre d'autres clés, non documentées mais utiles, par exemple. 

PHImageFileOrientationKey = 3;
PHImageFileSandboxExtensionTokenKey = "/private/var/mobile/Media/DCIM/100Apple/IMG_0780.JPG";
PHImageFileURLKey = "file:///var/mobile/Media/DCIM/100Apple/IMG_0780.JPG";
PHImageFileUTIKey = "public.jpeg";
PHImageResultDeliveredImageFormatKey = 9999;
PHImageResultIsDegradedKey = 0;
PHImageResultIsInCloudKey = 0;
PHImageResultIsPlaceholderKey = 0;
PHImageResultRequestIDKey = 1;
PHImageResultWantedImageFormatKey = 9999;

Amusez-vous. Linasses

1
Linasses

Je pense que cela est lié au fait que vous définissez PHImageRequestOptionsDeliveryModeOpportunistic. Notez que cela n'est même pas pris en charge pour le mode asynchrone (par défaut). Essayez PHImageRequestOptionsDeliveryModeHighQualityFormat intead.

0
xaphod