web-dev-qa-db-fra.com

didFinishPickingMediaWithInfo renvoie aucune photo

Je travaille pour capturer une image renvoyée en 4.0 en utilisant

- (void)imagePickerController:(UIImagePickerController *)picker 
    didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    [[picker parentViewController] dismissModalViewControllerAnimated:YES]; 

    // MediaType can be kUTTypeImage or kUTTypeMovie. If it's a movie then you
    // can get the URL to the actual file itself. This example only looks for images.
    //   
    NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType];
    // NSString* videoUrl = [info objectForKey:UIImagePickerControllerMediaURL];

    // Try getting the edited image first. If it doesn't exist then you get the
    // original image.
    //
    if (CFStringCompare((CFStringRef) mediaType,  kUTTypeImage, 0) == kCFCompareEqualTo) {               
        UIImage* picture = [info objectForKey:UIImagePickerControllerEditedImage];
        if (!picture)
            picture = [info objectForKey:UIImagePickerControllerOriginalImage];             

        // **picture is always nil
            // info dictionary count = 1


    }

}

Ce qui se passe, c'est que le dictionnaire d'informations revient toujours avec une seule entrée:

{UIImagePickerControllerMediaType = "public.image";

ce qui est génial, mais il n'y a jamais d'image.

J'utilisais un excellent exemple de ce forum pour le faire, et je suis presque sûr que les appels sont corrects, mais jamais une image.

Merci d'avance!

30
Rob Bonner

Je sais que c'est plusieurs mois plus tard, mais j'ai eu du mal avec cela pendant des heures, et j'ai trouvé cette même question partout sur ce site et iphonedevsdk.com, mais jamais avec une réponse de travail.

Pour résumer, si l'image a été choisie dans la photothèque/photothèque, cela a bien fonctionné, mais si l'image était une nouvelle prise de photo avec l'appareil photo, elle n'a jamais fonctionné. Eh bien, voici comment le faire fonctionner pour les deux:

Vous devez rejeter et libérer le UIImagePickerController avant vous essayez de faire quoi que ce soit avec le dictionnaire d'informations. Pour être super clair:

Cela ne fonctionne pas:

- (void)imagePickerController:(UIImagePickerController *)picker 
                      didFinishPickingMediaWithInfo:(NSDictionary *)info {

          // No good with the edited image (if you allowed editing)
  myUIImageView.image = [info objectForKey:UIImagePickerControllerEditedImage];
          // AND no good with the original image
  myUIImageView.image = [info objectForKey:UIImagePickerControllerOriginalImage];
          // AND no doing some other kind of assignment
  UIImage *myImage = [info objectForKey:UIImagePickerControllerEditedImage];

  [picker dismissModalViewControllerAnimated:YES];
  [picker release];
}

Dans tous ces cas, l'image sera nulle.

Cependant, via la magie de la libération du UIImagePickerController d'abord ...

Cela fonctionne:

- (void)imagePickerController:(UIImagePickerController *)picker 
                      didFinishPickingMediaWithInfo:(NSDictionary *)info {

  [picker dismissModalViewControllerAnimated:YES];
  [picker release];

          // Edited image works great (if you allowed editing)
  myUIImageView.image = [info objectForKey:UIImagePickerControllerEditedImage];
          // AND the original image works great
  myUIImageView.image = [info objectForKey:UIImagePickerControllerOriginalImage];
          // AND do whatever you want with it, (NSDictionary *)info is fine now
  UIImage *myImage = [info objectForKey:UIImagePickerControllerEditedImage];
}

C'est simple et fou, mais c'est tout.

54
Matthew Frederick

tandis que la réponse de Matthew Frederick est la plus populaire et a longtemps été la réponse appropriée, depuis iOS 5.0, Apple mis à disposition dismissViewControllerAnimated:completion:, pour remplacer le désormais obsolète (à partir d'iOS 6.0) dismissViewControllerAnimated:.

effectuer la récupération du dictionnaire d'informations sur l'image dans le bloc d'achèvement devrait, espérons-le, avoir plus de sens pour tous.

pour prendre son exemple d'en haut, cela ressemblerait maintenant à:

- (void)    imagePickerController:(UIImagePickerController *)picker 
    didFinishPickingMediaWithInfo:(NSDictionary *)info 
{
    [picker dismissViewControllerAnimated:YES completion:^{
          // Edited image works great (if you allowed editing)
        myUIImageView.image = [info objectForKey:UIImagePickerControllerEditedImage];
          // AND the original image works great
        myUIImageView.image = [info objectForKey:UIImagePickerControllerOriginalImage];
          // AND do whatever you want with it, (NSDictionary *)info is fine now
        UIImage *myImage = [info objectForKey:UIImagePickerControllerEditedImage];
    }];
}
17
john.k.doe

J'ai essayé tout ce qui précède, mais pas de chance sur le simulateur iPad 6.0/6.1, mais j'ai trouvé que les informations contiennent la clé "UIImagePickerControllerReferenceURL" et voici mon code:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
  [picker dismissViewControllerAnimated:YES completion:NULL];

  UIImage* image = [info objectForKey:UIImagePickerControllerOriginalImage];
  if(NULL == image){
      [MyImageLoader loadImageFromAssertByUrl:[info objectForKey:@"UIImagePickerControllerReferenceURL"]
                                   completion:^(UIImage* img){
                                        //img not null here
                                   }];
  }else{
      //image not null here
  }
}

et le code pour loadImageFromAssertByUrl est:

+(void) loadImageFromAssertByUrl:(NSURL *)url completion:(void (^)(UIImage*)) completion{
  ALAssetsLibrary *assetLibrary=[[ALAssetsLibrary alloc] init];
  [assetLibrary assetForURL:url resultBlock:^(ALAsset *asset) {
      ALAssetRepresentation *rep = [asset defaultRepresentation];
      Byte *buffer = (Byte*)malloc(rep.size);
      NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:rep.size error:nil];
      NSData *data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];
      UIImage* img = [UIImage imageWithData:data];
      completion(img);
  } failureBlock:^(NSError *err) {
      NSLog(@"Error: %@",[err localizedDescription]);
  }];
}
5
Alexey Suvorov

Il existe également un bug connu avec certaines versions de XCode et Mountain Lion. Vérifiez votre console pour ce message:

2013-01-17 21:36:34.946 3sure-ios[5341:1803] Named service 'com.Apple.PersistentURLTranslator.Gatekeeper' not found. assetsd is down or misconfigured. Things will not work the way you expect them to.

Cela ne fonctionnera probablement pas si ce message apparaît. Vérifiez votre application sur le véritable appareil iOS.

Néanmoins, le redémarrage du simulateur et de XCode semble résoudre le problème.

2
juanignaciosl

utilisation

[[UIImagePickerController alloc] init];

au lieu de

[[UIImagePickerController alloc] initWithNibName:(NSString *) bundle:(NSBundle *)];
1
yfguo

J'ai eu les mêmes symptômes, mais dans mon cas, il s'est avéré que j'avais une catégorie sur quelque chose dans la hiérarchie UIImagePickerController qui a remplacé "uuid" ou "setUUID"? Je suppose que CoreData a besoin de ces méthodes ou cela devient très, très confus, et la bibliothèque de ressources est entièrement constituée de CoreData.

0
Mason Cloud
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 
{

    [picker dismissViewControllerAnimated:YES completion:NULL];
    //Image picker for nil value 
    UIImage* selectedImage = [info objectForKey:UIImagePickerControllerOriginalImage];
    NSLog(@"my Info :: %@", info);

    if(NULL == selectedImage){
      UIImage * selectedImage =  [PhotoViewController loadImageFromAssertByUrl:[info objectForKey:@"UIImagePickerControllerReferenceURL"]
                                     completion:^(UIImage * selectedImage){
                                         //img not null here
                                         NSLog(@"img2 ::: %@", selectedImage);
                                         uploadImg.image = selectedImage;
                                         [self.view addSubview:PermissionView];
                                     }];
    }else{
        //image not null here
        NSLog(@"Up IMG00 :: %@", uploadImg.image);
        NSLog(@"Sel IMG00 :: %@", selectedImage);
        uploadImg.image = [selectedImage retain];
        NSLog(@"Up IMG22 :: %@", uploadImg.image);
        NSLog(@"Sel IMG22 :: %@", selectedImage);

    }
}


+(UIImage *) loadImageFromAssertByUrl:(NSURL *)url completion:(void (^)(UIImage*)) completion{


    __block UIImage* img;

    ALAssetsLibrary *assetLibrary=[[ALAssetsLibrary alloc] init];

    [assetLibrary assetForURL:url resultBlock:^(ALAsset *asset) {
        ALAssetRepresentation *rep = [asset defaultRepresentation];
        Byte *buffer = (Byte*)malloc(rep.size);
        NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:rep.size error:nil];
        NSData *data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];
        img = [UIImage imageWithData:data];
        completion(img);
        NSLog(@"img ::: %@", img);
    } failureBlock:^(NSError *err) {
        NSLog(@"Error: %@",[err localizedDescription]);
    }];

    return img;
}
0
user3328172