How to save exif data with the image using photos framework

I am developing an application to capture images using photos framework. There i want to store gsp data (longitude, latitude) as metadata of the image. I searched web about this and couldn't find any related information. Any help would be highly appreciated.

Replies

Here's some code I use to get exif meta data:


            if let imageSource = CGImageSourceCreateWithData(imageData, nil), properties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) as? [NSString: AnyObject] {
                NSLog("Image properties = \(properties)")
               
                if let exif = properties[kCGImagePropertyExifDictionary] as? [NSString: AnyObject] {
                    if let date = exif[kCGImagePropertyExifDateTimeOriginal] as? NSDate {
                        self.photoDate = date
                    }
                }
               
                if let pixelWidth = properties[kCGImagePropertyPixelWidth] as? NSNumber {
                    self.photoWidthInPixels = pixelWidth.floatValue
                }
                if let pixelHeight = properties[kCGImagePropertyPixelHeight] as? NSNumber {
                    self.photoHeightInPixels = pixelHeight.floatValue
                }
               
                if let orientation = properties[kCGImagePropertyOrientation] as? NSNumber where orientation.intValue >= 5 && orientation.intValue <= 8 {
                    let height = self.photoHeightInPixels
                    self.photoHeightInPixels = self.photoWidthInPixels
                    self.photoWidthInPixels = height
                }


                if let gps = properties[kCGImagePropertyGPSDictionary] as? [NSString: AnyObject] {
                    if let lattitude = gps[kCGImagePropertyGPSLatitude] as? NSNumber, longitude = gps[kCGImagePropertyGPSLongitude] as? NSNumber {
                        let lat = CLLocationDegrees(lattitude.floatValue); let long = CLLocationDegrees(longitude.floatValue)
                        self.location = CLLocation(latitude:lat, longitude: long)
                    }
                }
            }

Have you found a way to store to the image's metadata? We formerly stored the user's comments and other data with the image using the ALAssetsLibrary. Unfortunately, that has been deprecated and we haven't yet found a way to store data to the image's metadata with the Photo Framework. Apple Support has been of no help in resolving this loss of functionality.

You have to write the image to a temporary file and add the metadata to the temporary file using CGImageDestinationAddImage. Then you can read the data from the temporary file and save it to the Photos library by using [PHAssetChangeRequest creationRequestForAssetFromImageAtFileURL].

@chuckc192000


Could you please show me your code ?


I saved temporary jpeg data and added GPS metadata by using CGImageDestinationAddImage.

The result has GPS metadata but the file size was reduced from about 5MB to 3MB.

It seems lost thumbnail image and other data.


My code is like below,


- (void)saveImageDataToPhotoAlbum:(NSData *)originalData
{
    NSDictionary *dataDic = [self getDataAndMetadata:originalData];
   
    ALAssetsLibrary *assetsLib = [[ALAssetsLibrary alloc] init];
    [assetsLib writeImageDataToSavedPhotosAlbum:dataDic[@"data"]
                                       metadata:dataDic[@"metadata"]
                                completionBlock:^(NSURL *url, NSError *e) {
                                    [self addToMyAlbum:url];
                                }];
}
- (NSDictionary *)getDataAndMetadata:(NSData *)originalData
{
    CGImageSourceRef cimage = CGImageSourceCreateWithData((CFDataRef)originalData, nil);
    NSDictionary *metadata = (NSDictionary *)CGImageSourceCopyPropertiesAtIndex(cimage, 0, nil);
  
    NSMutableDictionary *metadataAsMutable = [NSMutableDictionary dictionaryWithDictionary:metadata];
    metadataAsMutable[(NSString *)kCGImagePropertyGPSDictionary] = self.myGpsDic;
  
    NSMutableData *dataForMetadataRemoval = [NSMutableData data];
    CGImageDestinationRef dest =
    CGImageDestinationCreateWithData((CFMutableDataRef)dataForMetadataRemoval, CGImageSourceGetType(cimage), 1, nil);
    CGImageDestinationAddImageFromSource(dest, cimage, 0, (CFDictionaryRef)metadataAsMutable);
    CGImageDestinationFinalize(dest);
    CFRelease(dest);
    [metadata release];
    CFRelease(cimage);
  
    return @{ @"data" : (dataForMetadataRemoval), @"metadata" : metadataAsMutable};
}
 return metadataAsMutable; 
}