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

ExifLib - A Fast Exif Data Extractor for .NET 2.0+

By , 8 Apr 2013
 
Exif Lib - test application

Introduction

ExifLib simply reads Exif tags (i.e., camera model, GPS data, date picture taken, shutter speed etc.) from JPEG files, without the overhead introduced by using the GDI+ classes located in System.Drawing.Imaging, and with less lines of code for the developer.

Background

I've been using a simple command line application to move my photos into subdirectories based on the date on which they were created. As with all other .NET Exif implementations I've seen, I was using the PropertyItem class located in System.Drawing.Imaging. While this does the job, I often found myself processing thousands of images at a time, and the .NET classes were just too slow for the job. ExifLib goes back to the JPEG/TIFF standard itself, and only reads the essentials, using little more than the file input classes in System.IO.

Using the Code

ExifLib is very simple, with only one class and one enum in the namespace. Just add a reference to ExifLib.dll, and you're good to go! An example follows:

using ExifLib;
...
...
...
// Instantiate the reader
ExifReader reader = new ExifReader(@"C:\temp\testImage.jpg");

// Extract the tag data using the ExifTags enumeration
DateTime datePictureTaken;
if (reader.GetTagValue<DateTime>(ExifTags.DateTimeDigitized, 
                                    out datePictureTaken))
{
    // Do whatever is required with the extracted information
    MessageBox.Show(this, string.Format("The picture was taken on {0}", 
       datePictureTaken), "Image information", MessageBoxButtons.OK);
}

Points of Interest

Something strange that I learned while writing this library is that while JPEG stipulates "Big Endian" encoding (i.e., numbers read from left to right), the TIFF standard allows Big or Little Endian encoding. Since the Exif tags are encoded using TIFF encoding, often the JPEG will be read using "Big Endian" encoding until the TIFF section is reached, at which point the encoding reverses and the rest of the document is read using "Little Endian" encoding.

During coding, I realised from a comment on the ExifWorks CodeProject article that it's possible to increase performance when using System.Drawing.Image by setting the constructor's validateImageData parameter to false. However, even when using this enhancement, ExifLib still performs 50% faster, possibly because it does not read the tag values until they're requested. I have also noticed that ExifLib performs similarly with small (<1MP) images, but scales better when loading larger images. The screenshot at the top of this page was produced using a 12MP image.

History

Version 1.1

  • Array extraction has been added, thanks to a comment from Justin Carasick. This is used in various fields, including GPS coordinates and Exif versioning. The previous version of ExifLib would only return the first element from an array.

Version 1.2

  • Fixed bug when retrieving data for fields shorter than 4 bytes, thanks to a comment from bartsy. The previous version of ExifLib would lose important data from these fields when processing big-endian encoded files.
  • Updated the project to Visual Studio 2010, refactored a little of the code. The project is still .NET 2.0+.

Version 1.3

  • Added the ability to extract JPEG encoded thumbnails from images, thanks to a comment from StyrianOak. Note that uncompressed (i.e. TIFF) encoded thumbnails are not supported, but since any camera which supports the DCF standard will produce JPEG thumbnails, this is a minor limitation.

Version 1.4

  • Added a constructor overload to allow reading of JPEG data from any seekable stream
  • Modified code to allow compiling for Windows Phone and Silverlight. The NuGet package now includes Windows Phone and Silverlight DLLs.
  • Improved support for null DateTime values thanks to comments from schurig and BrandonOrding
  • undefined Exif fields are now returned as byte[] instead of uint[]

NuGet Release

ExifLib is now available on nuget! Simply install from the Visual Studio Package Manager Console using Install-Package ExifLib.

License

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

About the Author

Simon McKenzie
Software Developer BreastScreen Victoria
Australia Australia
Member

Simon McKenzie has been working as a developer for 9 years, primarily in .NET and Java, with interests in imaging and GIS, particularly on mobile platforms. He is the author of the award winning MapSnap GPS, a moving map application for Windows Phone. He's also the author of the popular (free) high-speed ExifLib EXIF extractor for .NET.


Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionModify EXIF datamemberMember 100309438 May '13 - 2:22 
Do you have any plan about implementing modification of EXIF data? I want to add gps info because the CameraCaptureTask class just ignore it.
If you are not interesting, can you give me some tips about how to do it? I think that implementing a reverse gettagvalue should work
Cheers,
José
AnswerRe: Modify EXIF datamemberSimon McKenzie8 May '13 - 13:44 
Hi José,
 
Editing's quite a different task, and doesn't lend itself well to the design of the library. I recommend just using GDI+ - see this other answer for more details.
 
Cheers,
 
Simon
GeneralRe: Modify EXIF datamemberMember 100309438 May '13 - 21:32 
Thanks for your fast reply, Simon.
My problem is that in Windows Phone there is no GDI support, so I think that the only way I can do this is modifying the stream.
I started to modify the source code of your ExifLib to try to make the job, I created a BinaryWriter and reused a lot of your code, and the new method is very similar to GetTagBytes but when I should read the tagData I just wrote my new data (I respect the offsets if is needed). But my problem is that when I try to read what I wrote with a normal GetValueTag the data is the same as before I started to modify the Exif data.
 
If you are interested in helping/develop this feature, feel free to contact me and I will share with you the new source code.
 
Cheer,
José
GeneralRe: Modify EXIF datamemberSimon McKenzie9 May '13 - 13:44 
Hi José
 
Good luck with the writer - I'm not personally interested in contributing, but maybe you could start a new project on Sourceforge. I feel that this library exists to perform a single task, and perform it well, i.e. rapid reading of Exif data, but by all means, use the source as a starting point for your writer.
 
Cheers,
 
Simon
GeneralRe: Modify EXIF datamemberMember 1003094313 May '13 - 4:55 
Thanks Simon.
Finally I got the writer working, is not as generic as the reader is, but for gps works as expected.
By the way, I noticed that the Dispose method always close the stream, but I think that this is not always the expected behavior. If you use the reader with an stream you probably want to keep the stream openned. I already modified the code to work as I want, but maybe you want to change that in next releases.
 
Cheers,
José
GeneralRe: Modify EXIF datamemberSimon McKenzie13 May '13 - 15:25 
Good work, José.
 
Are you going to release your code somewhere? You make an interesting point about the stream being closed, but if you consider built-in classes like System.IO.BinaryReader, they have the same behaviour on Dispose. However, framework 4.5 adds an overload which allows the stream to be left open afterwards. Perhaps I will add a similar constructor overload to ExifReader.
 
Cheers,
 
Simon
GeneralRe: Modify EXIF datamemberMember 1003094313 May '13 - 21:17 
I wasn't planning to release the code because the writter is very specific and it will probably only work with GPS stuff (maybe other rational exif data). The dispose method that i modified is not working as I expected, I need to override the dispose method to be able to just close the binaryreader (I'm not able to call Dispose(bool), as its a protected method).
If you want me to share with you the code, I can give it to you, and do whatever you want.
Cheers,
José
QuestionGet OrientationmemberMember 100309435 May '13 - 22:17 
Hello, I was using this lib in my Windows Phone proyect for a long time (exiflib v1.0) but i just updated the lib to the last versión and i'm not very sure how to get the image orientation to rotate it. I used before "ExifOrientation" but seems that doesn't exist anymore. Can someone help me?
Thanks
AnswerRe: Get OrientationmemberSimon McKenzie6 May '13 - 1:06 
Here's how you'd do it:
 
using (var reader = new ExifReader(filename))
{
    ushort orientation;
    if (reader.GetTagValue(ExifTags.Orientation, out orientation))
        Console.WriteLine("Orientation: " + orientation);
}
 
I hope this helps!
 
Note that version 1.0 didn't have Windows Phone support, so it's possible that you were using a modified library (or a different one altogether). The ExifReader method signatures haven't changed much since the first version.
 
Cheers,
 
Simon
GeneralRe: Get OrientationmemberMember 100309436 May '13 - 1:17 
Thanks Simon for your fast reply,
I was able to get the orientation, but i can't see any const to check the exif value (i got the values from the old versión and compared them doing a switch-case).
So i have the function working, but if there is an "official" values where i can check my data would be great.
 
Cheers.

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

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130523.1 | Last Updated 9 Apr 2013
Article Copyright 2009 by Simon McKenzie
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid