{"id":26182854,"url":"https://github.com/coatsy/readimageexif","last_synced_at":"2026-04-20T18:02:31.516Z","repository":{"id":102381240,"uuid":"291568421","full_name":"coatsy/ReadImageExif","owner":"coatsy","description":null,"archived":false,"fork":false,"pushed_at":"2021-05-17T00:00:25.000Z","size":46,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-03-11T22:34:51.138Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/coatsy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-08-30T23:19:35.000Z","updated_at":"2021-05-17T00:00:27.000Z","dependencies_parsed_at":null,"dependency_job_id":"f5e08812-8c94-4609-a0c7-96e9dcfad6cc","html_url":"https://github.com/coatsy/ReadImageExif","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/coatsy/ReadImageExif","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coatsy%2FReadImageExif","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coatsy%2FReadImageExif/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coatsy%2FReadImageExif/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coatsy%2FReadImageExif/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/coatsy","download_url":"https://codeload.github.com/coatsy/ReadImageExif/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coatsy%2FReadImageExif/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32059139,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-20T11:35:06.609Z","status":"ssl_error","status_checked_at":"2026-04-20T11:34:48.899Z","response_time":94,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-03-11T22:32:39.874Z","updated_at":"2026-04-20T18:02:31.510Z","avatar_url":"https://github.com/coatsy.png","language":"C#","readme":"# Exif File Reader\n\nOver 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.:\n\nI used [ExifLib](https://www.nuget.org/packages/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](https://docs.microsoft.com/en-us/azure/cosmos-db/sql-query-geospatial-query) like\n\n``` SQL\nSELECT c.FileName FROM c\nWHERE ST_DISTANCE(c.ExifData.location, {\"type\": \"Point\", \"coordinates\":[151.555, -33.143]}) \u003c 10\n```\n\nand that returns the names of all the pictures taken within 10 m of that point.\n\nThere's also a [LINQ implementation of spatial queries](https://docs.microsoft.com/en-us/azure/cosmos-db/sql-query-geospatial-query#linq-querying-in-the-net-sdk) in the .NET Cosmos SDK\n\nI also worked out how to read User Secrets in .NET Core console apps\n​​​​​​\n## `GetExifData()` Extension Method\n\nCreated the `GetExifData()` extension method to grab all the EXIF data available for a `Path` string.\n\nI 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](./enum.xlsx). Then used a formula to generate the C# code to paste into the files.\n\nThis generated something like this for the extension method:\n\n``` CSharp\nstring gpsdestlatituderef; if (reader.GetTagValue\u003cstring\u003e(ExifTags.GPSDestLatitudeRef, out gpsdestlatituderef)) exifData.GPSDestLatitudeRef = gpsdestlatituderef;\n```\n\nand this in the class definition:\n\n``` CSharp\npublic string GPSDestLatitudeRef { get; set; }\n```\n\nNext, I ran the method over a selection of my JPEG files to see what broke.\n\nSometimes, the type was always wrong, so I updated the spreadsheet to:\n\n``` CSharp\nDouble gpsimgdirection; if (reader.GetTagValue\u003cDouble\u003e(ExifTags.GPSImgDirection, out gpsimgdirection)) exifData.GPSImgDirection = gpsimgdirection;\n```\n\nand\n\n``` CSharp\npublic Double GPSImgDirection { get; set; }\n```\n\nOther times, it varied between (I guess) Exif versions, so I ended up with a bunch of conditional logic:\n\n``` CSharp\nUInt32 imagewidth;\ntry\n{\n    if (reader.GetTagValue\u003cUInt32\u003e(ExifTags.ImageWidth, out imagewidth))\n        exifData.ImageWidth = imagewidth;\n}\ncatch (Exception)\n{\n    UInt16 imageWidth16;\n    if (reader.GetTagValue\u003cUInt16\u003e(ExifTags.ImageWidth, out imageWidth16))\n        exifData.ImageWidth = (UInt32)imageWidth16;\n}\n```\n\nThrough a series of trial and error, I got to the current implementation which doesn't break on any of my current sample of JPEGs.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoatsy%2Freadimageexif","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcoatsy%2Freadimageexif","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoatsy%2Freadimageexif/lists"}