5

En iOS 4.2 cuando uso UIImagePickerController para que el usuario seleccione una imagen de la biblioteca de fotos éstas son las claves del diccionario que se devuelven a mí:A partir de los resultados de UIImagePickerControlleHow, ¿cómo consigo JPEG con los metadatos incluidos?

2011-03-02 13:15:59.518 xxx[15098:307] didFinishPickingMediaWithInfo: 
    info dictionary: { 
    UIImagePickerControllerMediaType = "public.image"; 
    UIImagePickerControllerOriginalImage = "<UIImage: 0x3405d0>"; 
    UIImagePickerControllerReferenceURL = 
     "assets-library://asset/asset.JPG?id=1000000050&ext=JPG"; 
} 

El uso de una o más de estas teclas, ¿cómo puedo conseguir una representación JPEG que incluiría los metadatos de la imagen (como la información de exposición y los datos de ubicación del GPS) de manera que pueda subir eso a alguna parte y tener los metadatos incluidos (no eliminados).

que veo de respuesta muy buena de Warren Burton en Display image from URL retrieved from ALAsset in iPhone? cómo utilizar el UIImagePickerControllerReferenceURL y el método ALAssetsLibrary assetForURL llegar al ALAsset y la ALAssetRepresentation. Pero, ¿qué hago entonces para llegar al JPEG que incluye todos los metadatos?

¿O hay un mecanismo a través del UIImage?

El fondo aquí es que quiero llegar JPEG con los metadatos incluidos en ella ...

Respuesta

7

Desde hice la pregunta que he hecho un poco más de la experimentación y creo saber la respuesta ahora. Todos los resultados se incorporaron en iOS 4.2, que es todo lo que importa ...

En primer lugar, nos estaban usando UIImageJPEGRepresentation ala:

NSData *imageData = UIImageJPEGRepresentation(self.selectedImage, 0.9); 

que parece no darle (la mayor parte) de los metadatos (EXIF, GPS, etc.) que está en la imagen. Es suficiente y creo que eso es bien conocido.

Mi prueba muestra que el JPEG en la "representación predeterminada" para el elemento de imagen contendrá todos los metadatos, incluida la información EXIF ​​y GPS (suponiendo que esté allí en primer lugar). Puede obtener esa imagen pasando de la URL del activo al Activo a la representación predeterminada del activo (ALAssetRepresentation) y luego utilizando el método/mensaje getBytes para recuperar los bytes de la imagen JPEG. Esa secuencia de bytes tiene los metadatos mencionados anteriormente.

Aquí hay un código de ejemplo que utilizo para esto. Se necesita una URL de activo, que se supone que es para una imagen, y devuelve NSData con el JPEG. Cuidado con este hotel con respecto a su uso, manipulación en el código de error, etc.

/* 
* Example invocation assuming that info is the dictionary returned by 
* didFinishPickingMediaWithInfo (see original SO question where 
* UIImagePickerControllerReferenceURL = "assets-library://asset/asset.JPG?id=1000000050&ext=JPG"). 
*/ 
[self getJPEGFromAssetForURL:[info objectForKey:UIImagePickerControllerReferenceURL]]; 
// ... 

/* 
* Take Asset URL and set imageJPEG property to NSData containing the 
* associated JPEG, including the metadata we're after. 
*/ 
-(void)getJPEGFromAssetForURL:(NSURL *)url { 
    ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init]; 
    [assetslibrary assetForURL:url 
     resultBlock: ^(ALAsset *myasset) { 
      ALAssetRepresentation *rep = [myasset defaultRepresentation]; 
#if DEBUG 
      NSLog(@"getJPEGFromAssetForURL: default asset representation for %@: uti: %@ size: %lld url: %@ orientation: %d scale: %f metadata: %@", 
      url, [rep UTI], [rep size], [rep url], [rep orientation], 
      [rep scale], [rep metadata]); 
#endif 

      Byte *buf = malloc([rep size]); // will be freed automatically when associated NSData is deallocated 
      NSError *err = nil; 
      NSUInteger bytes = [rep getBytes:buf fromOffset:0LL 
           length:[rep size] error:&err]; 
      if (err || bytes == 0) { 
       // Are err and bytes == 0 redundant? Doc says 0 return means 
       // error occurred which presumably means NSError is returned. 

       NSLog(@"error from getBytes: %@", err); 
       self.imageJPEG = nil; 
       return; 
      } 
      self.imageJPEG = [NSData dataWithBytesNoCopy:buf length:[rep size] 
            freeWhenDone:YES]; // YES means free malloc'ed buf that backs this when deallocated 
     } 
     failureBlock: ^(NSError *err) { 
      NSLog(@"can't get asset %@: %@", url, err); 
     }]; 
    [assetslibrary release]; 
} 
+0

Para nuevo aviso, assetLib es asíncrona, por lo que el imagejpeg podría ser nulo si no se precarga. – rnaud

+1

+1. Gran alivio para finalmente ver los metadatos impresos en la consola. ¡Buena respuesta! – gary

Cuestiones relacionadas