4

I have previously asked this question: How to write exif metadata to an image.

I now have found a way to inject metadata. However, it results in a copy of the image into memory. With large images, and the need to already have a copy in memory, this is going to have performance, and possibly cause a memory crash.

Is there a correct way to inject metadata without having to make a copy of the image? Perhaps it could be tacked on to a file, after it is written to disk?

I would prefer native implementations, without having to resort to a third party library just for this, if at all possible.

Community
  • 1
  • 1
akaru
  • 6,299
  • 9
  • 63
  • 102
  • If you are adding metadata to a file, then the file will grow in size. In order to manage this you can read it into memory, add the data and write it back (what the OS apparently does) or write you own code which reads/writes smaller chunks of the file at a time. – BitBank Mar 22 '12 at 21:01
  • Yes, I don't want to read it completely into memory, but all Apple APIs I know require that. Reading/writing a little is what I'm referring to, although I don't know the proper format and don't wish to corrupt the file. – akaru Mar 23 '12 at 03:23

3 Answers3

1

This question could require a small or large amount of code depending on what you need. EXIF data is stored in a JPEG APP1 marker (FFE1). It looks very much like a TIFF file with a TIFF header, IFD and individual tags with the data. If you can build your own APP1 marker segment, then inserting it or replacing it in a JPEG file is trivial. If you are looking to read the metadata from an existing file, add some new tags and then write it back, that can be more involved. The tricky part of EXIF data are those tags which require more than 4-bytes. Each TIFF tag is 12 bytes: 2-byte tag, 2-byte data type, 4-byte count, 4-byte data. If the data doesn't fit completely in the 4 bytes of the tag, then the tag specifies an absolute offset into the file of where to find the data. If the existing data has any tags with data like this (e.g. make, model, capture date, capture time, etc), you will need to repack that data by fixing the offsets and then add your own. In a nutshell:

1) If you are adding a pre-made APP1 marker to a JPEG file, this is simple and requires little code.

2) If you need to read the existing meta-data from a JPEG file, add your own and write it back, the code is a bit more involved. It's not "difficult", but it involves a lot more than just reading and writing blocks of data.

Start by reading the TIFF 6.0 spec to understand the tag and directory structure:

TIFF 6.0 spec

Next, take a look at the JPEG EXIF spec:

EXIF 2.2 Spec

BitBank
  • 8,500
  • 3
  • 28
  • 46
  • I wil have the exif data as an NSDictionary, so reading is not the problem. Do you know of any libraries which can do the details of creating the markers? I can understand the spec, but of course I'd rather not have to reinvent the wheel. – akaru Mar 27 '12 at 18:04
0

I would expect the existing exif manipulator software can do it, but haven't tested.

Links:

XTL
  • 851
  • 1
  • 8
  • 23
0

CGImageSourceRef could be used to get image properties including its thumbnail without loading all image data into memory. This way memory is not wasted by UIImage and NSData.

CGImageSourceRef imageSource = CGImageSourceCreateWithURL((CFURLRef)[NSURL fileURLWithPath:path], NULL);

Then save CGImageDestinationRef adding the source image and exif data.

CGImageDestinationAddImageFromSource (destRef,    
                                      imageSource,
                                      0,
                                     (CFDictionaryRef)propertes );//exif
BOOL success = CGImageDestinationFinalize(destRef);
Alex L
  • 8,419
  • 6
  • 43
  • 51
  • I've been looking through the docs on this. I can understand how the data is retrieved, but not understanding how to inject this back into the original image on disk. If I create a CGImageSourceRef of just the thumbnail, would I then be overwriting the original image with it when calling CGImageDestinationAddImageFromSource? – akaru Aug 01 '12 at 22:34
  • Check out Apple's SquareCam example. The writeCGImageToCameraRoll method has the creating destination, adding source data and then saving it to disk/album. – Alex L Aug 07 '12 at 21:18
  • @AlexL How do I retrieve the thumbnail present in the metadata? There is no 'key' for accessing the thumbnail! – neeraj Mar 12 '13 at 05:29
  • 1
    @neeraj Check out Apple's reference "Creating a Thumbnail Image from an Image Source" example http://developer.apple.com/library/ios/documentation/GraphicsImaging/Conceptual/ImageIOGuide/imageio_source/ikpg_source.html#//apple_ref/doc/uid/TP40005462-CH218-DontLinkElementID_6 – Alex L Mar 12 '13 at 15:03
  • @AlexL It says "Some image source files contain thumbnail images that you can retrieve". But it doesn't talk about any method of doing it. Instead, it says if thumbnail is not there, this is the way to make it. What if it is there? How do I get it? – neeraj Mar 12 '13 at 18:41
  • 1
    @neeraj I don't know the answer to your question but I assume that when kCGImageSourceCreateThumbnailFromImageIfAbsent is true and a thumnail already exists, it will be reused. Otherwise, what is the purpose of that option. – Alex L Mar 12 '13 at 19:27
  • Whoa! I didn't see that part.. I just assumed that it would only be for making the thumbnail. I didn't look at the key name. I'll try that out.. Thanks! – neeraj Mar 13 '13 at 08:40