Skip to content

Repository files navigation

Exif File Reader

Over the weekend I had a play with some cool bits - probably old news to most, but I have about 10000 pics on my "Skydrive Camera Roll" in OneDrive and I wanted to get all the pics taken from one spot.:

I used ExifLib (now .NET Standard so I could use it in my .NET5 console app) to grab all the Exif Data from every jpg using an extension method (so I could do a filename.ReadExifData()) and wrote it to a Cosmos container including a new property called location with the lat and long. I made sure the container knew I was using geography data (Lat/Lon) and now I can just do a Cosmos DB spatial query like

SELECT c.FileName FROM c
WHERE ST_DISTANCE(c.ExifData.location, {"type""Point""coordinates":[151.555-33.143]}) < 10

and that returns the names of all the pictures taken within 10 m of that point.

There's also a LINQ implementation of spatial queries in the .NET Cosmos SDK

I also worked out how to read User Secrets in .NET Core console apps ​​​​​​

GetExifData() Extension Method

Created the GetExifData() extension method to grab all the EXIF data available for a Path string.

I generated the first pass of the population of the ExifData class and the extraction method by using Enum.GetValues() on the ExifLib.ExifTags enum and pasting the output into a spreadsheet. Then used a formula to generate the C# code to paste into the files.

This generated something like this for the extension method:

string gpsdestlatituderef; if (reader.GetTagValue<string>(ExifTags.GPSDestLatitudeRef, out gpsdestlatituderef)) exifData.GPSDestLatitudeRef = gpsdestlatituderef;

and this in the class definition:

public string GPSDestLatitudeRef { get; set; }

Next, I ran the method over a selection of my JPEG files to see what broke.

Sometimes, the type was always wrong, so I updated the spreadsheet to:

Double gpsimgdirection; if (reader.GetTagValue<Double>(ExifTags.GPSImgDirection, out gpsimgdirection)) exifData.GPSImgDirection = gpsimgdirection;

and

public Double GPSImgDirection { get; set; }

Other times, it varied between (I guess) Exif versions, so I ended up with a bunch of conditional logic:

UInt32 imagewidth;
try
{
    if (reader.GetTagValue<UInt32>(ExifTags.ImageWidth, out imagewidth))
        exifData.ImageWidth = imagewidth;
}
catch (Exception)
{
    UInt16 imageWidth16;
    if (reader.GetTagValue<UInt16>(ExifTags.ImageWidth, out imageWidth16))
        exifData.ImageWidth = (UInt32)imageWidth16;
}

Through a series of trial and error, I got to the current implementation which doesn't break on any of my current sample of JPEGs.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages