Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS saving photo to Camera Roll does not preserve EXIF/GPS metadata

Tags:

ios

uiimage

exif

I know a UIImage can be saved into Camera Roll with UIImageWriteToSavedPhotosAlbum, but this approach strips all metadata from the original file (EXIF, GPS data, etc). Is there any way to save the original file, rather than just the image data into the iOS device's Camera Roll?

Edit: I guess I should have been a bit more specific. The aim is to save a duplicate of an existing JPEG file into a user's Camera Roll. What's the most efficient way to do this?

like image 450
SaltyNuts Avatar asked Dec 03 '12 19:12

SaltyNuts


3 Answers

Depending on how you have your image to save you can chose one of the methods provided by the ALAssetsLibrary.

– writeImageDataToSavedPhotosAlbum:metadata:completionBlock:

– writeImageToSavedPhotosAlbum:metadata:completionBlock:

(Depending on if you have the image as an actual UIImage, or as NSData)

http://developer.apple.com/library/ios/#documentation/AssetsLibrary/Reference/ALAssetsLibrary_Class/Reference/Reference.html

Take notice on the fact that you have to have set the correct keys for the dictionary or they might not be saved correctly.

Here is an example for the GPS information:

NSDictionary *gpsDict = [NSDictionary dictionaryWithObjectsAndKeys:
                 [NSNumber numberWithFloat:fabs(loc.coordinate.latitude)], kCGImagePropertyGPSLatitude, 
                 ((loc.coordinate.latitude >= 0) ? @"N" : @"S"), kCGImagePropertyGPSLatitudeRef, 
                 [NSNumber numberWithFloat:fabs(loc.coordinate.longitude)], kCGImagePropertyGPSLongitude, 
                 ((loc.coordinate.longitude >= 0) ? @"E" : @"W"), kCGImagePropertyGPSLongitudeRef, 
                 [formatter stringFromDate:[loc timestamp]], kCGImagePropertyGPSTimeStamp, 
                 [NSNumber numberWithFloat:fabs(loc.altitude)], kCGImagePropertyGPSAltitude, 
                 nil];

And here is a list of the keys:

http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Reference/CGImageProperties_Reference/Reference/reference.html#//apple_ref/doc/uid/TP40005103

like image 57
Pochi Avatar answered Nov 02 '22 18:11

Pochi


UIImagePickerControllerDelegate is what you're looking for.

Starting in iOS 4.0, you can save still-image metadata, along with a still image, to the Camera Roll. To do this, use the writeImageToSavedPhotosAlbum:metadata:completionBlock: method of the Assets Library framework. See the description for the UIImagePickerControllerMediaMetadata key.

UIImagePickerControllerDelegate Protocol Reference

like image 1
Segev Avatar answered Nov 02 '22 20:11

Segev


For a Swift solution that uses the Photos API (ALAssetLibrary is deprecated in iOS 9), you can see my solution to this problem here, including sample code.

With the Photos API, the key thing to note is that the .location property of a PHAsset does NOT embed the CLLocation metadata into the file itself, so using an EXIF viewer will not turn up any results.

To get around this, you must embed any metadata changes directly into the Data of the image itself before writing it to the camera roll using the Photos API (or, for iOS versions prior to 9, you must write a temporary file using the Data with the embedded metadata and create the PHAsset from the file's URL).

Also note that the act of converting image Data to a UIImage appears to strip metadata, so be careful with that.

like image 1
Undrea Avatar answered Nov 02 '22 18:11

Undrea