Click here to Skip to main content
Click here to Skip to main content

Understanding and Reading Exif Data

, 14 Dec 2009 CPOL
Rate this:
Please Sign up or sign in to vote.
This article explains how to retrieve valuable image information from the Exif data found in JPEG images, and provides a Silverlight class library to perform this task entirely on the client's machine

Introduction

Silverlight is a great environment for developing rich web applications. Using Silverlight, you can easily perform expensive tasks on the client's machine, reducing the cost of bandwidth and processing power required by more traditional web applications.

This article explains how to retrieve valuable image information from the Exif data found in JPEG images, and provides a Silverlight class library to perform this task entirely on the client's machine.

Note: Unfortunately for Silverlight developers, the sandboxed .Net framework available to them does not expose the GDI+ wrappers implemented in the System.Drawing.Imaging namespace - at least not at the time of writing this article. These wrappers include all the necessary tools to retrieve various informations from image metadata, so if they're available don't waste your time re-inventing the wheel.

Related Work

A great article was written by Simon McKenzie on the same subject: ExifLib - A Fast Exif Data Extractor for .NET 2.0. The libraries even have the same name... small world. I haven't looked at his code, but the article states that he is not using the System.Drawing.Imaging methods as well - so it should work just fine in Silverlight with no major modifications.

This article differs in that it explains the basics of the Jpeg and Exif formats, and was written specifically for Silverlight.

The Jpeg File Format

Understanding the general structure of a Jpeg file is important to extract the Exif data. A Jpeg image is delimited by two byte markers. The first marker byte is always 0xFF, while the second identifies what comes after it. For example, the mandatory "Start Of Image marker", or SOI, is defined by the number 0xD8. This is why every Jpeg image starts with the sequence 0xFF 0xD8. With the exception of the SOI marker, each marker is followed by two bytes specifying the length of the marker' section data in bytes. If our goal is to extract Exif data from a Jpeg image, then we're looking for the Exif marker: 0xE1.

The Exif Format

Following the two bytes indicating the Exif section length, the ASCII string "Exif" is found, followed by two zero bytes. The next two bytes indicates the endianess of the data stored in the Exif directories. If II is found, meaning that Intel ordering is used, then the byte order is little endian. If MM is found, meaning Motorola ordering is used, then the byte order is big endian. Any primitive read beyond this point needs to consider the Exif byte order.

The Exif data is stored in a directory structure: the Image File Directory, or IFD structure. The first four bytes store the length of the directory in bytes. Then, two bytes are used to indicate the number of entries, or tags, found in this directory. Each Exif entry is first defined by its tag identifier (two bytes), then its format (two bytes) and finally its component count (four bytes). Exif formats are defined as follows:

  1. Unsigned Byte (1 byte per component)
  2. ASCII String (1 bpc)
  3. Unsigned Short (2 bpc)
  4. Unsigned Long (4 bpc)
  5. Unsigned Rational (8 bpc, 4 for the numerator and 4 for the denominator)
  6. Signed Byte
  7. Undefined (1 bpc)
  8. Signed Short
  9. Signed Long
  10. Signed Rational
  11. Single (4 bpc)
  12. Double (8 bpc)

If the total byte count exceeds four bytes for an Exif entry, the next four bytes represent an offset into the Exif section from where to find the actual entry data. This way it is possible to iterate through a list of Exif entries simply by skipping 12 bytes.

IFDs can be nested under the root Exif directory. The tag number 0x8769 defines the start of a new Exif directory. Other IFD tags are also used to group tag numbers into categories. For example, 0x8825 is the tag number for the GPS IFD. At the end of an IFD, another IFD can be defined, creating a linked list. This linkage is defined by the next four bytes after the end of the directory's list of entries. If this integer is an offset that falls within the boundaries of the Exif section, it defines the starting point of the next IFD.

Thumbnail Data

A camera creating a 10 megapixel image creates a 2-7 MB Jpeg file on its memory card, depending on the image. Storing a raw 10,000,000 pixel color image in main memory requires at least 28 MB. Keeping a few hundreds of those monster images in memory is not very practical, especially if your only goal is to display a small preview of the image. Even if memory is available, decoding a Jpeg image is a very expensive operation, and decoding a few hundreds of them would take minutes today. Again, not very practical.

So, how is your digital camera able to preview a dozen or more of those 10 MP pictures, in under a second? Using thumbnails, of course. A thumbnail is a smaller version of the full sized image, and is used to preview the image without having to decode it or store it in memory. The Exif format includes entries for thumbnail data, so digital cameras, when creating a Jpeg image, also typically create a 160x120 version of the same image and store it in the Exif section of the image. This image can be decoded very quickly, and takes under 60K of memory.

Exif entries also contain other very useful informations, such as the date the image was taken, the camera model, user comments, the exposure time, whether or not the camera flash was used, and even GPS coordinates in recent models or cell phones.

ExifLib

class-diagram.png

ExifLib is a small class library that can be used to rapidly and efficiently parse Exif data found in a given Jpeg stream. The ExifReader.ReadJpeg static method takes a System.IO.FileInfo instance for input, and returns a new JpegInfo object. If the JpegInfo.IsValid field is set to True, then the object is now filled with all the available Exif data found in the Jpeg stream.

Note that not all known Exif tags are covered by this library. If more information needs to be extracted, the ExifTag class can be modified along with the appropriate tag enumerations.

ExifSL

ExifSL.png

In order to test and demonstrate the ExifLib capabilities, I wrote a little Silverlight application that lets you load and preview Jpeg images, as well as display some of the Exif information extracted. When no Exif thumbnail is found, it falls back on loading the entire image using the BitmapImage.SetSource method. Just click on the "Add Images" button and select a few Jpeg images to get it started.

Conclusion

Understanding and using image file formats and metadata is a first step in any image processing application. I hope this little utility will save you some time.

References

  1. JPEG - Wikipedia
  2. JPEG.org
  3. EXIF.org
  4. Exif file format
  5. Exif Jpeg header manipulation tool

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Etienne Whittom
Software Developer
United States United States
Etienne Whittom is a software engineer currently living in Washington state.
 
Since 2004, he worked at several companies including Electronic Arts (Montreal, QC) and Microsoft (Redmond, WA), where he learned much about crunch times, live site issues, escalations, down times, pattents, design reviews, code reviews, security reviews, planning and commitments.
 
He also picked up a few things about software development along the way...
 
He loves good wines, good food, hiking, running, and refer to himself in the third person.

Comments and Discussions

 
QuestionHow to expose more EXIF fields? [modified] PinmemberMember 881438912-Apr-12 5:57 
GeneralWriting Exif Data Pinmemberoliv261-Sep-10 0:36 
GeneralRe: Writing Exif Data PinmemberEtienne Whittom2-Sep-10 3:14 
Hi Olivier,
 
As the person on stackoverflow pointed out, this library can be used for reading Exif data only, but can easily be adapted to update the Exif data on a given file: read the Exif data using the reader, read the remaining of the file in memory (the image data), update the Exif data (take extra care in updating the various offsets as well), write the updated Exif data, write the remaining of the file.
 
The OpenFileDialog control lets you select multiple files at a time, but the selected files will not open for write (OpenWrite is security critical I believe). To save files on disk, you'll need to use the SaveFileDialog control. Since asking the user to save each and every file he previously opened is not very practical, you may want to write every file in an archive (single file) and leave the original files untouched.
 
I hope this helps,
-Etienne.

GeneralRe: Writing Exif Data Pinmemberoliv262-Sep-10 3:36 
GeneralRe: Writing Exif Data Pinmemberihayes91624-Jan-14 8:10 
GeneralEXIF versus Windows API Codepack Pinmemberrctaubert9-Jan-10 4:35 
AnswerRe: EXIF versus Windows API Codepack PinmemberEtienne Whittom9-Jan-10 7:55 
GeneralRe: EXIF versus Windows API Codepack Pinmemberrctaubert10-Jan-10 2:52 
GeneralReading Exif Data explicitly vs Pinmemberrctaubert22-Dec-09 4:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141223.1 | Last Updated 14 Dec 2009
Article Copyright 2009 by Etienne Whittom
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid