85

I would like to write a small program in C# which goes through my jpeg photos and, for example, sorts them into dated folders (using MY dating conventions, dammit...).

Does anyone know a relatively easy way to get at the EXIF data such as Date And Time or Exposure programatically? Thanks!

Joel in Gö
  • 7,460
  • 9
  • 47
  • 77
  • The BCL's built-in support for image metadata is quite limited. I have been working with metadata such as Exif since 2002 and have a simple yet powerful [library for extracting such data for .NET](https://github.com/drewnoakes/metadata-extractor-dotnet). – Drew Noakes Jul 09 '15 at 22:54
  • 2
    Why was this closed? It does focus on one problem, getting EXIT from files. There also is a clear and focused answer. – mafu Mar 24 '20 at 02:16

9 Answers9

55

As suggested, you can use some 3rd party library, or do it manually (which is not that much work), but the simplest and the most flexible is to perhaps use the built-in functionality in .NET. For more see:

I say "it’s the most flexible" because .NET does not try to interpret or coalesce the data in any way. For each EXIF you basically get an array of bytes. This may be good or bad depending on how much control you actually want.

Also, I should point out that the property list does not in fact directly correspond to the EXIF values. EXIF itself is stored in multiple tables with overlapping ID’s, but .NET puts everything in one list and redefines ID’s of some items. But as long as you don’t care about the precise EXIF ID’s, you should be fine with the .NET mapping.


Edit: It's possible to do it without loading the full image following this answer: https://stackoverflow.com/a/552642/2097240

Daniel Möller
  • 84,878
  • 18
  • 192
  • 214
Jan Zich
  • 14,993
  • 18
  • 61
  • 73
  • 10
    Accessing Bitmap.PropertyItems requires reading the whole file into memory. If you create a Bitmap, access PropertyItems and do nothing else, you can use XPerf to see that your app accessed the image file and read it all into memory. For my computer, a 3.4mb file cost >700ms worth of IO, just to get EXIF via PropertyItems :(. – Tristan Aug 06 '11 at 22:53
  • 4
    By comparison, Picasa's PhotoViewer reads just 20 - 30k from each file it touches. Those reads cost only ~25ms. Wow; I'd love to chat with the guy/girl that wrote that stuff. (Data was collected by profiling PhotoViewer's startup using XPerf). – Tristan Aug 09 '11 at 14:32
  • @Tristan: Useful information, however how often do you access the image metadata without also wanting the image itself? I am sure there are some cases, but I think in the majority case, one would be displaying the image (or otherwise working with it's data) AND it's metadata at the same time. – jrista Nov 26 '13 at 08:21
  • 5
    @jrista How often do I want just the metadata? Most of the time. For example, imagine you want to sort or filter a set of images by a piece of metadata. Sorting by date taken is a pretty common thing to do, and to get that info you have to go into the metadata. – Tristan Nov 26 '13 at 19:28
  • @Tristan: But what are you sorting? A grid display of thumbnails? Just saying, at least in many of the cases I can think of, you are going to want the image often enough. I suspect you would cache recently accessed info, too. I think it is a bit of a moot point these days anyway, though...the new WPF media & imaging framework supports reading all metadata, EXIF and IPTC, and it will only load the data it actually needs to. If you want efficient metadata access, just use the new WPF framework instead of the old GDI framework, and you should have the efficiency you are looking for. – jrista Nov 27 '13 at 00:50
  • We're kind of getting off topic. I'd be happy to continue as a PM, if you like. – Tristan Nov 27 '13 at 17:31
  • 2
    This answer shows how to do it with `PropertyItems` **without loading the whole image**: https://stackoverflow.com/a/552642 – Daniel Möller Oct 02 '19 at 16:26
29

Check out this metadata extractor. It is written in Java but has also been ported to C#. I have used the Java version to write a small utility to rename my jpeg files based on the date and model tags. Very easy to use.


EDIT metadata-extractor supports .NET too. It's a very fast and simple library for accessing metadata from images and videos.

It fully supports Exif, as well as IPTC, XMP and many other types of metadata from file types including JPEG, PNG, GIF, PNG, ICO, WebP, PSD, ...

var directories = ImageMetadataReader.ReadMetadata(imagePath);

// print out all metadata
foreach (var directory in directories)
foreach (var tag in directory.Tags)
    Console.WriteLine($"{directory.Name} - {tag.Name} = {tag.Description}");

// access the date time
var subIfdDirectory = directories.OfType<ExifSubIfdDirectory>().FirstOrDefault();
var dateTime = subIfdDirectory?.GetDateTime(ExifDirectoryBase.TagDateTime);

It's available via NuGet and the code's on GitHub.

Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
Dave Griffiths
  • 1,962
  • 19
  • 22
  • This is great if your Windows app always shows iPhone images sideways or upside down. There's an `Orientation` tag in each image that's ordinarily a magic number, but this library tells you the rotation (i.e. `Rotate 180` or `Rotate 90 CCW`). – Chris Akridge Jan 12 '20 at 21:07
10

You can use TagLib# which is used by applications such as F-Spot. Besides Exif, it will read a good amount of metadata formats for image, audio and video.

I also like ExifUtils API but it is buggy and is not actively developed.

smola
  • 863
  • 8
  • 15
9

Here is a link to another similar SO question, which has an answer pointing to this good article on "Reading, writing and photo metadata" in .Net.

Community
  • 1
  • 1
Joel in Gö
  • 7,460
  • 9
  • 47
  • 77
  • An alternate question with **very good answer** [is here](https://stackoverflow.com/q/10494796/2803565) which points to [ExifLib - A Fast Exif Data Extractor for .NET 2.0+](https://www.codeproject.com/Articles/36342/ExifLib-A-Fast-Exif-Data-Extractor-for-NET-2-0) – S.Serpooshan Jun 24 '17 at 06:19
  • Heads up - The link "Reading, writing and photo metadata" is broken. – Losbear Mar 01 '22 at 18:42
6

Image class has PropertyItems and PropertyIdList properties. You can use them.

idursun
  • 6,261
  • 1
  • 37
  • 51
5

Getting EXIF data from a JPEG image involves:

  1. Seeking to the JPEG markers which mentions the beginning of the EXIF data,. e.g. normally oxFFE1 is the marker inserted while encoding EXIF data, which is a APPlication segment, where EXIF data goes.
  2. Parse all the data from say 0xFFE1 to 0xFFE2 . This data would be stream of bytes, in the JPEG encoded file.
  3. ASCII equivalent of these bytes would contain various information related to Image Date, Camera Model Name, Exposure etc...
goldenmean
  • 18,376
  • 54
  • 154
  • 211
3

The command line tool ExifTool by Phil Harvey works with dozens of images formats - including plenty of proprietary RAW formats - and can manipulate a variety of metadata formats including EXIF, GPS, IPTC, XMP, JFIF.

Very easy to use, lightweight, impressive application.

Kirk Broadhurst
  • 27,836
  • 16
  • 104
  • 169
  • 1
    ExifTool is an amazing lib/tool, but it's written in Perl so using it from C# involves launching an external process. – Drew Noakes Jul 27 '15 at 21:39
0

Recently, I used this .NET Metadata API. I have also written a blog post about it, that shows reading, updating, and removing the EXIF data from images using C#.

using (Metadata metadata = new Metadata("image.jpg"))
{
    IExif root = metadata.GetRootPackage() as IExif;
    if (root != null && root.ExifPackage != null)
    {
        Console.WriteLine(root.ExifPackage.DateTime);
     }
}
0

fastest way is to use windows api codec that doesn't open file and instead uses cached exif information

var prop = ShellFile.FromFilePath(f).Properties;
var Dimensions = prop.GetProperty("Dimensions").ValueAsObject.ToString(); 
//1280 x 800

Gray Programmerz
  • 479
  • 1
  • 5
  • 22