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..
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!
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With