2010-06-21 9 views
30

Sto lavorando per catturare un'immagine che viene restituito in 4.0 utilizzandodidFinishPickingMediaWithInfo ritorno nullo foto

- (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 


    } 

} 

Quello che sta accadendo è che il dizionario informazioni torna sempre con una singola voce:

{ UIImagePickerControllerMediaType = "public.image";

che è ottimo, ma non c'è mai un'immagine.

Stavo usando un ottimo esempio da questo forum per fare questo, e sono abbastanza sicuro che le chiamate siano corrette, ma mai un'immagine.

Grazie in anticipo!

+0

Chi prende? Huge Karma enorme su questo !!!! –

+1

Hai lo stesso problema –

+0

Lo stesso numero qui – codemonkey

risposta

52

So che questo è molti mesi più tardi, ma ho faticato con questo per ore, e ho trovato questa stessa domanda in tutto questo sito e iphonedevsdk.com, ma mai con una risposta funzionante.

Per riassumere, se l'immagine è stata selezionata dal rullino fotografico/libreria fotografica, ha funzionato correttamente, ma se l'immagine era una nuova foto, prendere con la fotocamera non ha mai funzionato. Bene, ecco come farlo funzionare per entrambi:

È necessario chiudere e rilasciare UIImagePickerController prima di si tenta di fare qualsiasi cosa con il dizionario delle informazioni. Per essere super-chiaro:

Questo non funziona:

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

In tutti questi casi l'immagine sarà pari a zero.

Tuttavia, tramite la magia di liberare l'UIImagePickerController prima ...

Questo funziona:

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

Pazzo semplice, ma questo è tutto ciò che devi fare.

+12

sei serio?!! è questo il mio problema! OH MIO DIO. * _dies_ * –

+8

Come funziona con ARC? – rasmus

+0

Non l'ho ancora provato, ma un paio di opzioni mi vengono in mente come possibilità. Il primo è copiare il dizionario delle informazioni - 'NSDictionary * infoDictionary = [Dizionario NSDictionaryWithDictionary: informazioni]' - e quindi estrarre il selettore - 'picker = nil'. Non sono sicuro che funzionerà. L'altra opzione che funzionerà quasi sicuramente è quella di creare un file separato per il codice di selezione delle immagini in Xcode e impostare tale file in modo che non utilizzi ARC, mantenendo la soluzione qui. –

0

Ho avuto gli stessi sintomi, ma nel mio caso si è scoperto che avevo una categoria su qualcosa nella gerarchia UIImagePickerController che ha annullato "uuid" o "setUUID"? Immagino che CoreData abbia bisogno di questi metodi o diventa molto, molto confuso, e la libreria di risorse è tutta roba CoreData.

17

mentre la risposta di Matthew Frederick è più popolare ed è stata a lungo la risposta appropriata, a partire da iOS 5.0, apple reso disponibile dismissViewControllerAnimated:completion:, per sostituire l'ormai deprecato (come da iOS 6.0) dismissViewControllerAnimated:.

eseguire il recupero del dizionario di informazioni sull'immagine nel blocco di completamento dovrebbe, si spera, avere più senso per tutti.

a prendere il suo esempio dall'alto, sarebbe ora simile:

- (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]; 
    }]; 
} 
+1

Sei sicuro che il suo '[picker dismissModalViewControllerAnimated: YES completion:' e non '[picker dismissViewControllerAnimated: YES completion:^(void)'? –

+0

corretto. grazie per aver notato l'errore cut'n'paste. –

+2

Questo produce ancora un risultato nullo per me, eseguendo un'app per iPhone nell'emulatore iPad (iOS 6.1). – Desty

2

C'è anche un bug noto con alcune versioni di XCode e Mountain Lion.Controlla la tua console per questo messaggio:

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.

Probabilmente non funzionerà se viene visualizzato il messaggio. Controlla la tua app sul dispositivo iOS reale.

Tuttavia, riavviare sia il simulatore che XCode sembra risolvere il problema.

+0

Non ho visto questo errore, ma sul simulatore l'immagine è nullo sul dispositivo funziona ... –

1

uso

[[UIImagePickerController alloc] init]; 

invece di

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

Ho provato tutti al di sopra, ma senza fortuna su iPad 6.0/6.1 simulatore, ma ho scoperto che informazioni contiene la chiave "UIImagePickerControllerReferenceURL" e qui è il mio codice:

- (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 
    } 
} 

e il codice per loadImageFromAssertByUrl è:

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

Grazie! Non posso credere che abbiamo bisogno di fare questo genere di cose per aggirare un bug nell'emulatore iPad che è stato segnalato almeno un anno fa, ma almeno può essere risolto ... – Desty

0
-(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; 
} 
+1

Si prega di formattare e spiegare la risposta! – ohlmar

+1

Ho avuto lo stesso problema in iPad Air e iOS 8, e ho risolto il mio problema con questi codici. Grazie. – dobiho

-1

seguito Passi deve essere seguita:
1) Fai UIActionSheet
2) Sulla selezione del tipo di sorgente necessario - resrouces carico
3) didFinishPickingMediaWithInfo - immagine impostata da un'immagine dizionario recieved

- (IBAction)actionButtonUpload:(id)sender { 

      UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self 

cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"Camera",@"Photo Library", nil]; 

     [actionSheet showInView:self.view]; 

    } 

    #pragma mark -- UIActionSheet Delegate 
    -(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{ 

     UIImagePickerController *picker = [[UIImagePickerController alloc] init]; 

     picker.delegate = self; 
     picker.allowsEditing = YES; 
     UIAlertView *alert; 


     switch (buttonIndex) { 
      case 0: 
       if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { 

        NSLog(@"No camera!"); 
        picker.sourceType = UIImagePickerControllerSourceTypeCamera; 
        [self presentViewController:picker animated:YES completion:NULL]; 


       } else { 

        alert = [[UIAlertView alloc]initWithTitle:@"Alumnikonnect" message:@"Camera is not available, please select a different media" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; 

        [alert show]; 

       } 
       break; 
      case 1: 

       if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) { 

        picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; 
        [self presentViewController:picker animated:YES completion:NULL]; 


       } else { 

        alert = [[UIAlertView alloc]initWithTitle:@"Alumnikonnect" message:@"Photolibrary is not available, please select a different media" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; 

        [alert show]; 

       } 

       break; 

     } 

    } 


    #pragma mark - Image picker delegate 

    - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 
    { 
      self.imageEventPic.layer.cornerRadius = self.imageEventPic.frame.size.height /2; 
      self.imageEventPic.layer.masksToBounds = YES; 
      self.imageEventPic.layer.borderWidth = 0; 
      self.imageEventPic.layer.borderWidth = 1.0f; 
      self.imageEventPic.layer.borderColor = [UIColor colorWithRed:0.212 green:0.255 blue:0.302 alpha:1.000].CGColor; 


     self.labelUploadPic.hidden = YES; 

     self.imageEventPic.image = info[UIImagePickerControllerOriginalImage]; 

     [self dismissViewControllerAnimated:YES completion:NULL]; 

    } 


    - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker 
    { 
     [self dismissViewControllerAnimated:YES completion:NULL]; 

    } 

    -(UIImage*)imageWithImage:(UIImage*)image 
       scaledToSize:(CGSize)newSize; 
    { 
     UIGraphicsBeginImageContext(newSize); 

     [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)]; 

     UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); 

     UIGraphicsEndImageContext(); 

     return newImage; 

    } 
Problemi correlati