Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Exif data from UIImage - UIImagePickerController [duplicate]

How can we get Exif information from UIImage selected from UIImagePickerController?

I had done much R&D for this and got many replies but still failed to implement this.

I had gone through this this and this link

Please help me to solve this problem.

Thanks in advance..

like image 843
Mehul Mistri Avatar asked Mar 19 '12 07:03

Mehul Mistri


2 Answers

Interesting question! I came up with the following solution working for images picked from your photo library (note my code is using ARC):

Import AssetsLibrary.framework and ImageIO.framework.

Then include the needed classes inside your .h-file:

#import <AssetsLibrary/ALAsset.h> #import <AssetsLibrary/ALAssetRepresentation.h> #import <ImageIO/CGImageSource.h> #import <ImageIO/CGImageProperties.h> 

And put this inside your imagePickerController:didFinishPickingMediaWithInfo: delegate method:

ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; [library assetForURL:[info objectForKey:UIImagePickerControllerReferenceURL]     resultBlock:^(ALAsset *asset) {          ALAssetRepresentation *image_representation = [asset defaultRepresentation];          // create a buffer to hold image data          uint8_t *buffer = (Byte*)malloc(image_representation.size);         NSUInteger length = [image_representation getBytes:buffer fromOffset: 0.0  length:image_representation.size error:nil];          if (length != 0)  {              // buffer -> NSData object; free buffer afterwards             NSData *adata = [[NSData alloc] initWithBytesNoCopy:buffer length:image_representation.size freeWhenDone:YES];              // identify image type (jpeg, png, RAW file, ...) using UTI hint             NSDictionary* sourceOptionsDict = [NSDictionary dictionaryWithObjectsAndKeys:(id)[image_representation UTI] ,kCGImageSourceTypeIdentifierHint,nil];              // create CGImageSource with NSData             CGImageSourceRef sourceRef = CGImageSourceCreateWithData((__bridge CFDataRef) adata,  (__bridge CFDictionaryRef) sourceOptionsDict);              // get imagePropertiesDictionary             CFDictionaryRef imagePropertiesDictionary;             imagePropertiesDictionary = CGImageSourceCopyPropertiesAtIndex(sourceRef,0, NULL);              // get exif data             CFDictionaryRef exif = (CFDictionaryRef)CFDictionaryGetValue(imagePropertiesDictionary, kCGImagePropertyExifDictionary);             NSDictionary *exif_dict = (__bridge NSDictionary*)exif;             NSLog(@"exif_dict: %@",exif_dict);              // save image WITH meta data             NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];             NSURL *fileURL = nil;             CGImageRef imageRef = CGImageSourceCreateImageAtIndex(sourceRef, 0, imagePropertiesDictionary);              if (![[sourceOptionsDict objectForKey:@"kCGImageSourceTypeIdentifierHint"] isEqualToString:@"public.tiff"])                      {                          fileURL = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@.%@",                                                            documentsDirectory,                                                            @"myimage",                                                            [[[sourceOptionsDict objectForKey:@"kCGImageSourceTypeIdentifierHint"] componentsSeparatedByString:@"."] objectAtIndex:1]                                                            ]];                           CGImageDestinationRef dr = CGImageDestinationCreateWithURL ((__bridge CFURLRef)fileURL,                                                                                      (__bridge CFStringRef)[sourceOptionsDict objectForKey:@"kCGImageSourceTypeIdentifierHint"],                                                                                      1,                                                                                      NULL                                                                                     );               CGImageDestinationAddImage(dr, imageRef, imagePropertiesDictionary);               CGImageDestinationFinalize(dr);               CFRelease(dr);             }             else             {               NSLog(@"no valid kCGImageSourceTypeIdentifierHint found …");             }              // clean up             CFRelease(imageRef);             CFRelease(imagePropertiesDictionary);             CFRelease(sourceRef);         }         else {             NSLog(@"image_representation buffer length == 0");         }     }     failureBlock:^(NSError *error) {         NSLog(@"couldn't get asset: %@", error);     } ]; 

One thing I noticed is, that iOS will ask the user to allow location services – if he denies, you won't be abled to get the image data …

EDIT

Added code to save the image including its meta data. It's a quick approach, so maybe there is a better way, but it works!

like image 186
dom Avatar answered Oct 09 '22 01:10

dom


These answers all seem extremely complex. If the image has been saved to the Camera Roll, and you have the ALAsset (either from UIImagePicker or ALAssetLibrary) you can get the metadata like so:

asset.defaultRepresentation.metadata; 

If you want to save that image from camera roll to another location (say in Sandbox/Documents) simply do:

CGImageDestinationRef imageDestinationRef   = CGImageDestinationCreateWithURL((__bridge CFURLRef)urlToSaveTo, kUTTypeJPEG, 1, NULL); CFDictionaryRef imagePropertiesRef          = (__bridge CFDictionaryRef)asset.defaultRepresentation.metadata;  CGImageDestinationAddImage(imageDestinationRef, asset.defaultRepresentation.fullResolutionImage, imagePropertiesRef); if (!CGImageDestinationFinalize(imageDestinationRef)) NSLog(@"Failed to copy photo on save to %@", urlToSaveTo);  CFRelease(imageDestinationRef); 
like image 24
Andrew Theis Avatar answered Oct 09 '22 00:10

Andrew Theis