I'm using the new ImageIO framework in iOS 4.1. I successfully retrieve the exif metadata using the following:
CFDictionaryRef metadataDict = CMGetAttachment(sampleBuffer, kCGImagePropertyExifDictionary , NULL);
Reading it out, it appears valid. Saving an image out works, but there is never any exif data in the image.
CGImageDestinationRef myImageDest = CGImageDestinationCreateWithURL((CFURLRef) docurl, kUTTypeJPEG, 1, NULL); // Add the image to the destination using previously saved options. CGImageDestinationAddImage(myImageDest, iref, NULL); //add back exif NSDictionary *props = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithFloat:.1], kCGImageDestinationLossyCompressionQuality, metadataDict, kCGImagePropertyExifDictionary, //the exif metadata nil]; //kCGImagePropertyExifAuxDictionary CGImageDestinationSetProperties(myImageDest, (CFDictionaryRef) props); // Finalize the image destination. bool status = CGImageDestinationFinalize(myImageDest);
You need first to copy the exif files located here google exif to your project, then use the following code : ExifInterface exif = new ExifInterface(); exif. readExif(exifVar. getAbsolutePath()); exif.
Use Shift date to shift the date, and Shift time to shift the time. The calendar on the left here shows the original Date Created information stored in pictures' EXIF data. In the second calendar, choose a new date for the pictures. Use Shift date at the top to change the picture-taken date.
Yes EXIF data can be altered. You can change the fields in post with certain programs. You can also fake the date simply by changing the date and time of the camera before taking the picture, there's nothing that says a camera has to have the exact date and time.
The following blog post is where I got my answer when I had issues with modifying and saving Exif data Caffeinated Cocoa. This works on iOS.
Here is my test code for writing Exif and GPS data. It pretty much a copy and paste of the code from the above blog. I am using this to write exif data to a captured image.
NSData *jpeg = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer] ; CGImageSourceRef source ; source = CGImageSourceCreateWithData((CFDataRef)jpeg, NULL); //get all the metadata in the image NSDictionary *metadata = (NSDictionary *) CGImageSourceCopyPropertiesAtIndex(source,0,NULL); //make the metadata dictionary mutable so we can add properties to it NSMutableDictionary *metadataAsMutable = [[metadata mutableCopy]autorelease]; [metadata release]; NSMutableDictionary *EXIFDictionary = [[[metadataAsMutable objectForKey:(NSString *)kCGImagePropertyExifDictionary]mutableCopy]autorelease]; NSMutableDictionary *GPSDictionary = [[[metadataAsMutable objectForKey:(NSString *)kCGImagePropertyGPSDictionary]mutableCopy]autorelease]; if(!EXIFDictionary) { //if the image does not have an EXIF dictionary (not all images do), then create one for us to use EXIFDictionary = [NSMutableDictionary dictionary]; } if(!GPSDictionary) { GPSDictionary = [NSMutableDictionary dictionary]; } //Setup GPS dict [GPSDictionary setValue:[NSNumber numberWithFloat:_lat] forKey:(NSString*)kCGImagePropertyGPSLatitude]; [GPSDictionary setValue:[NSNumber numberWithFloat:_lon] forKey:(NSString*)kCGImagePropertyGPSLongitude]; [GPSDictionary setValue:lat_ref forKey:(NSString*)kCGImagePropertyGPSLatitudeRef]; [GPSDictionary setValue:lon_ref forKey:(NSString*)kCGImagePropertyGPSLongitudeRef]; [GPSDictionary setValue:[NSNumber numberWithFloat:_alt] forKey:(NSString*)kCGImagePropertyGPSAltitude]; [GPSDictionary setValue:[NSNumber numberWithShort:alt_ref] forKey:(NSString*)kCGImagePropertyGPSAltitudeRef]; [GPSDictionary setValue:[NSNumber numberWithFloat:_heading] forKey:(NSString*)kCGImagePropertyGPSImgDirection]; [GPSDictionary setValue:[NSString stringWithFormat:@"%c",_headingRef] forKey:(NSString*)kCGImagePropertyGPSImgDirectionRef]; [EXIFDictionary setValue:xml forKey:(NSString *)kCGImagePropertyExifUserComment]; //add our modified EXIF data back into the image’s metadata [metadataAsMutable setObject:EXIFDictionary forKey:(NSString *)kCGImagePropertyExifDictionary]; [metadataAsMutable setObject:GPSDictionary forKey:(NSString *)kCGImagePropertyGPSDictionary]; CFStringRef UTI = CGImageSourceGetType(source); //this is the type of image (e.g., public.jpeg) //this will be the data CGImageDestinationRef will write into NSMutableData *dest_data = [NSMutableData data]; CGImageDestinationRef destination = CGImageDestinationCreateWithData((CFMutableDataRef)dest_data,UTI,1,NULL); if(!destination) { NSLog(@"***Could not create image destination ***"); } //add the image contained in the image source to the destination, overidding the old metadata with our modified metadata CGImageDestinationAddImageFromSource(destination,source,0, (CFDictionaryRef) metadataAsMutable); //tell the destination to write the image data and metadata into our data object. //It will return false if something goes wrong BOOL success = NO; success = CGImageDestinationFinalize(destination); if(!success) { NSLog(@"***Could not create data from image destination ***"); } //now we have the data ready to go, so do whatever you want with it //here we just write it to disk at the same path we were passed [dest_data writeToFile:file atomically:YES]; //cleanup CFRelease(destination); CFRelease(source);
I tried Steve's answer and it works, but I think it's slow for large images because it's duplicating the entire image.
You can set the properties directly on the CMSampleBuffer using CMSetAttachments. Just do this before calling jpegStillImageNSDataRepresentation
CFDictionaryRef metaDict = CMCopyDictionaryOfAttachments(NULL, imageSampleBuffer, kCMAttachmentMode_ShouldPropagate); CFMutableDictionaryRef mutable = CFDictionaryCreateMutableCopy(NULL, 0, metaDict); NSMutableDictionary * mutableGPS = [self getGPSDictionaryForLocation:self.myLocation]; CFDictionarySetValue(mutable, kCGImagePropertyGPSDictionary, mutableGPS); // set the dictionary back to the buffer CMSetAttachments(imageSampleBuffer, mutable, kCMAttachmentMode_ShouldPropagate);
And the method getGPSDictionaryForLocation: can be found here:
Saving Geotag info with photo on iOS4.1
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