2010-06-21 11 views
30

estoy trabajando para capturar una imagen que se devuelve en 4,0 utilizandodidFinishPickingMediaWithInfo foto de retorno nula

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


    } 

} 

Lo que ocurre es que el diccionario de información siempre regresa con una sola entrada:

{ UIImagePickerControllerMediaType = "public.image";

que es genial, pero nunca hay una imagen.

Estaba usando un gran ejemplo de este foro para hacer esto, y estoy bastante seguro de que las llamadas son correctas, pero nunca una imagen.

¡Gracias de antemano!

+0

¿Alguna opinión? Enorme bache Karma en este !!!! –

+1

Tengo el mismo problema –

+0

Mismo problema aquí – codemonkey

Respuesta

52

Sé que esto es muchos meses después, pero luché con esto durante horas, y encontré esta misma pregunta en todo este sitio y iphonedevsdk.com, pero nunca con una respuesta funcional.

En resumen, si la imagen fue tomada de la biblioteca de rollo/fotografía de la cámara funcionó bien, pero si la imagen era una toma de fotografía nueva con la cámara, nunca funcionó. Bueno, aquí está cómo hacer que funcione para ambos:

Tienes que descartar y liberar el UIImagePickerController antes de intentas hacer algo con el diccionario de información. Para ser de gran nitidez:

esto no funciona:

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

En todos esos casos, la imagen será igual a cero.

Sin embargo, a través de la magia de la liberación de la primera UIImagePickerController ...

Esto funciona:

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

loco simple, pero eso es todo lo que hay que hacer.

+12

¿Estás hablando en serio? ¡este es mi problema! DIOS MIO. * _dies_ * –

+8

¿Cómo funciona esto con ARC? – rasmus

+0

No lo he probado todavía, pero me vienen a la mente un par de opciones. El primero es copiar el diccionario de información - 'NSDictionary * infoDictionary = [NSDictionary dictionaryWithDictionary: info]' - y luego eliminar el selector - 'picker = nil'. No estoy seguro si eso funcionará. La otra opción que seguramente funcionará es crear un archivo separado para el código de selección de imagen en Xcode y configurar ese archivo para que no use ARC, manteniendo la solución aquí. –

0

Tuve los mismos síntomas, pero en mi caso resultó que tenía una categoría en algo en la jerarquía UIImagePickerController que anulaba "uuid" o "setUUID"? Supongo que CoreData necesita estos métodos o se vuelve muy, muy confuso, y la biblioteca de activos es todo material de CoreData.

17

mientras que la respuesta de Matthew Frederick es la más popular y ha sido durante mucho tiempo la respuesta adecuada, desde iOS 5.0, apple disponible dismissViewControllerAnimated:completion:, para reemplazar la ahora obsoleta (a partir de iOS 6.0) dismissViewControllerAnimated:.

realizar la recuperación de diccionario de información de imagen en el bloque de finalización debería tener más sentido para todos.

a tomar su ejemplo de arriba, sería ahora el siguiente aspecto:

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

Está seguro de que es '[picker dismissModalViewControllerAnimated: YES completion:' and not '[picker dismissViewControllerAnimated: YES completion:^(void)'? –

+0

corregido. gracias por notar el error cut'n'paste –

+2

Esto todavía produce un resultado nulo para mí, ejecutando una aplicación de iPhone en el emulador de iPad (iOS 6.1). – Desty

2

También hay un fallo conocido con algunas versiones de XCode y león de montaña.Compruebe su consola para este mensaje:

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.

Es probable que no va a funcionar si aparece ese mensaje. Verifique su aplicación en el dispositivo iOS real.

Sin embargo, reiniciar tanto el simulador como XCode parece solucionar el problema.

+0

No vi este error, pero en el simulador la imagen es nula en el dispositivo funciona ... –

1

uso

[[UIImagePickerController alloc] init]; 

en lugar de

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

He intentado todo lo anterior, pero sin suerte en el iPad 6.0/6.1 simulador, sin embargo, me he dado cuenta que contiene información clave "UIImagePickerControllerReferenceURL" y aquí está mi código:

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

y el código de loadImageFromAssertByUrl es:

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

¡Gracias! No puedo creer que tengamos que hacer este tipo de cosas para solucionar un error en el emulador de iPad que se informó hace al menos un año, pero al menos se puede solucionar ... – 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

¡Formatee y explique su respuesta! – ohlmar

+1

Tuve el mismo problema en iPad Air e iOS 8, y resolví mi problema con estos códigos. Gracias. – dobiho

-1

siguientes pasos debe ser seguido:
1) Hacer UIActionSheet
2) En la selección del tipo de fuente necesaria - resrouces carga
3) didFinishPickingMediaWithInfo - establecer una imagen de la imagen Diccionario recibido

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

    } 
Cuestiones relacionadas