Skip to content

Instantly share code, notes, and snippets.

@ridercz
Created August 18, 2025 18:26
Show Gist options
  • Save ridercz/45e7ef18284a1f5574c6903425c97e50 to your computer and use it in GitHub Desktop.
Save ridercz/45e7ef18284a1f5574c6903425c97e50 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"id": "fc1ac59f",
"metadata": {},
"source": [
"# Working with EXIF metadata in C# with ImageSharp"
]
},
{
"cell_type": "markdown",
"id": "a30401d6",
"metadata": {},
"source": [
"## Setup\n",
"\n",
"We need to reference the `SixLabors.ImageSharp` [NuGet package](https://sixlabors.com/products/imagesharp/). Note: If you use ImageSharp for profit, you might need to purchase a [commercial license subscription](https://sixlabors.com/pricing/), which can get quite expensive. If you need free solution for commercial use, use for example the `MetadataExtractor` library."
]
},
{
"cell_type": "code",
"execution_count": 79,
"id": "b0462eb6",
"metadata": {
"language_info": {
"name": "polyglot-notebook"
},
"polyglot_notebook": {
"kernelName": "csharp"
}
},
"outputs": [
{
"data": {
"text/html": [
"<div><div></div><div></div><div><strong>Installed Packages</strong><ul><li><span>SixLabors.ImageSharp, 3.1.11</span></li></ul></div></div>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"#r \"nuget: SixLabors.ImageSharp\""
]
},
{
"cell_type": "markdown",
"id": "8b13c6d2",
"metadata": {},
"source": [
"We define the namespaces we will be using later:"
]
},
{
"cell_type": "code",
"execution_count": 80,
"metadata": {
"language_info": {
"name": "polyglot-notebook"
},
"polyglot_notebook": {
"kernelName": "csharp"
}
},
"outputs": [],
"source": [
"using SixLabors.ImageSharp;\n",
"using SixLabors.ImageSharp.Metadata.Profiles.Exif;"
]
},
{
"cell_type": "markdown",
"id": "8330e79f",
"metadata": {},
"source": [
"Also define the name of image file we are working with:"
]
},
{
"cell_type": "code",
"execution_count": 81,
"metadata": {
"language_info": {
"name": "polyglot-notebook"
},
"polyglot_notebook": {
"kernelName": "csharp"
}
},
"outputs": [],
"source": [
"var imageFileName = @\"demo.jpg\";"
]
},
{
"cell_type": "markdown",
"id": "940b280b",
"metadata": {},
"source": [
"## Show raw data"
]
},
{
"cell_type": "code",
"execution_count": 82,
"metadata": {
"language_info": {
"name": "polyglot-notebook"
},
"polyglot_notebook": {
"kernelName": "csharp"
}
},
"outputs": [
{
"data": {
"text/csv": [
"Tag,Type,IsArray,Value\r\n",
"ImageWidth,Short,False,4000\r\n",
"ImageLength,Short,False,1800\r\n",
"Orientation,Short,False,1\r\n",
"ResolutionUnit,Short,False,2\r\n",
"YCbCrPositioning,Short,False,2\r\n",
"544,Long,False,0\r\n",
"545,Long,False,0\r\n",
"546,Long,False,0\r\n",
"547,Long,False,0\r\n",
"548,Long,False,0\r\n",
"ExposureProgram,Short,False,0\r\n",
"ISOSpeedRatings,Short,True,System.UInt16[]\r\n",
"SensitivityType,Short,False,0\r\n",
"RecommendedExposureIndex,Long,False,0\r\n",
"ExifVersion,Undefined,True,System.Byte[]\r\n",
"ComponentsConfiguration,Undefined,True,System.Byte[]\r\n",
"MeteringMode,Short,False,2\r\n",
"LightSource,Short,False,255\r\n",
"Flash,Short,False,0\r\n",
"SubsecTime,Ascii,False,503\r\n",
"SubsecTimeOriginal,Ascii,False,503\r\n",
"SubsecTimeDigitized,Ascii,False,503\r\n",
"FlashpixVersion,Undefined,True,System.Byte[]\r\n",
"ColorSpace,Short,False,1\r\n",
"PixelXDimension,Short,False,4000\r\n",
"PixelYDimension,Short,False,1800\r\n",
"InteroperabilityIFD,Long,False,3891\r\n",
"SensingMethod,Short,False,1\r\n",
"SceneType,Undefined,False,1\r\n",
"ExposureMode,Short,False,0\r\n",
"WhiteBalance,Short,False,0\r\n",
"FocalLengthIn35mmFilm,Short,False,0\r\n",
"SceneCaptureType,Short,False,0\r\n",
"GPSVersionID,Byte,True,System.Byte[]\r\n",
"GPSLatitudeRef,Ascii,False,N\r\n",
"GPSLongitudeRef,Ascii,False,E\r\n",
"GPSAltitudeRef,Byte,False,0\r\n",
"ImageDescription,Ascii,False,\r\n",
"Make,Ascii,False,motorola\r\n",
"Model,Ascii,False,\"motorola edge 20 lite\"\r\n",
"XResolution,Rational,False,72\r\n",
"YResolution,Rational,False,72\r\n",
"Software,Ascii,False,\r\n",
"DateTime,Ascii,False,\"2025:06:27 15:57:16\"\r\n",
"549,Ascii,False,\r\n",
"ExposureTime,Rational,False,5230/1000000\r\n",
"FNumber,Rational,False,1900/1000\r\n",
"DateTimeOriginal,Ascii,False,\"2025:06:27 15:57:16\"\r\n",
"DateTimeDigitized,Ascii,False,\"2025:06:27 15:57:16\"\r\n",
"ShutterSpeedValue,SignedRational,False,5230/1000000\r\n",
"ApertureValue,Rational,False,1900/1000\r\n",
"BrightnessValue,SignedRational,False,0/10\r\n",
"ExposureBiasValue,SignedRational,False,0/10\r\n",
"MaxApertureValue,Rational,False,0/100\r\n",
"FocalLength,Rational,False,5880/1000\r\n",
"MakerNote,Undefined,True,System.Byte[]\r\n",
"DigitalZoomRatio,Rational,False,100/100\r\n",
"GPSLatitude,Rational,True,SixLabors.ImageSharp.Rational[]\r\n",
"GPSLongitude,Rational,True,SixLabors.ImageSharp.Rational[]\r\n",
"GPSAltitude,Rational,False,0\r\n",
"GPSTimestamp,Rational,True,SixLabors.ImageSharp.Rational[]\r\n",
"GPSProcessingMethod,Undefined,False,CELLID\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\r\n",
"GPSDateStamp,Ascii,False,2025:06:27\r\n"
],
"text/html": [
"<table><thead><tr><td><span>Tag</span></td><td><span>Type</span></td><td><span>IsArray</span></td><td><span>Value</span></td></tr></thead><tbody><tr><td>ImageWidth</td><td><span>Short</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><details class=\"dni-treeview\"><summary><span class=\"dni-code-hint\"><code>4000</code></span></summary><div><table><thead><tr></tr></thead><tbody></tbody></table></div></details></td></tr><tr><td>ImageLength</td><td><span>Short</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><details class=\"dni-treeview\"><summary><span class=\"dni-code-hint\"><code>1800</code></span></summary><div><table><thead><tr></tr></thead><tbody></tbody></table></div></details></td></tr><tr><td>Orientation</td><td><span>Short</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>1</pre></div></td></tr><tr><td>ResolutionUnit</td><td><span>Short</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>2</pre></div></td></tr><tr><td>YCbCrPositioning</td><td><span>Short</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>2</pre></div></td></tr><tr><td>544</td><td><span>Long</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>0</pre></div></td></tr><tr><td>545</td><td><span>Long</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>0</pre></div></td></tr><tr><td>546</td><td><span>Long</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>0</pre></div></td></tr><tr><td>547</td><td><span>Long</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>0</pre></div></td></tr><tr><td>548</td><td><span>Long</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>0</pre></div></td></tr><tr><td>ExposureProgram</td><td><span>Short</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>0</pre></div></td></tr><tr><td>ISOSpeedRatings</td><td><span>Short</span></td><td><div class=\"dni-plaintext\"><pre>True</pre></div></td><td><div class=\"dni-plaintext\"><pre>[ 100 ]</pre></div></td></tr><tr><td>SensitivityType</td><td><span>Short</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>0</pre></div></td></tr><tr><td>RecommendedExposureIndex</td><td><span>Long</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>0</pre></div></td></tr><tr><td>ExifVersion</td><td><span>Undefined</span></td><td><div class=\"dni-plaintext\"><pre>True</pre></div></td><td><div class=\"dni-plaintext\"><pre>[ 48, 50, 50, 48 ]</pre></div></td></tr><tr><td>ComponentsConfiguration</td><td><span>Undefined</span></td><td><div class=\"dni-plaintext\"><pre>True</pre></div></td><td><div class=\"dni-plaintext\"><pre>[ 1, 2, 3, 0 ]</pre></div></td></tr><tr><td>MeteringMode</td><td><span>Short</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>2</pre></div></td></tr><tr><td>LightSource</td><td><span>Short</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>255</pre></div></td></tr><tr><td>Flash</td><td><span>Short</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>0</pre></div></td></tr><tr><td>SubsecTime</td><td><span>Ascii</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td>503</td></tr><tr><td colspan=\"4\"><i>(43 more)</i></td></tr></tbody></table><style>\r\n",
".dni-code-hint {\r\n",
" font-style: italic;\r\n",
" overflow: hidden;\r\n",
" white-space: nowrap;\r\n",
"}\r\n",
".dni-treeview {\r\n",
" white-space: nowrap;\r\n",
"}\r\n",
".dni-treeview td {\r\n",
" vertical-align: top;\r\n",
" text-align: start;\r\n",
"}\r\n",
"details.dni-treeview {\r\n",
" padding-left: 1em;\r\n",
"}\r\n",
"table td {\r\n",
" text-align: start;\r\n",
"}\r\n",
"table tr { \r\n",
" vertical-align: top; \r\n",
" margin: 0em 0px;\r\n",
"}\r\n",
"table tr td pre \r\n",
"{ \r\n",
" vertical-align: top !important; \r\n",
" margin: 0em 0px !important;\r\n",
"} \r\n",
"table th {\r\n",
" text-align: start;\r\n",
"}\r\n",
"</style>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"using (Image image = Image.Load(imageFileName)) {\n",
" var exifProfile = image.Metadata.ExifProfile;\n",
" if (exifProfile != null) {\n",
" var results = exifProfile.Values.Select(p=> new {\n",
" Tag = p.Tag.ToString(),\n",
" Type = p.DataType,\n",
" IsArray = p.IsArray,\n",
" Value = p.GetValue()\n",
" });\n",
" results.DisplayTable();\n",
" } else {\n",
" Console.WriteLine(\"No EXIF metadata found.\");\n",
" }\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "d097968a",
"metadata": {},
"source": [
"## Format the data usefully\n",
"\n",
"Define helper method to convert raw values to some readable output:"
]
},
{
"cell_type": "code",
"execution_count": 83,
"metadata": {
"language_info": {
"name": "polyglot-notebook"
},
"polyglot_notebook": {
"kernelName": "csharp"
}
},
"outputs": [
{
"data": {
"text/csv": [
"Tag,Type,IsArray,RawValue,FormattedValue\r\n",
"ImageWidth,Short,False,4000,4000\r\n",
"ImageLength,Short,False,1800,1800\r\n",
"Orientation,Short,False,1,\"Top Left\"\r\n",
"ResolutionUnit,Short,False,2,2\r\n",
"YCbCrPositioning,Short,False,2,2\r\n",
"544,Long,False,0,0\r\n",
"545,Long,False,0,0\r\n",
"546,Long,False,0,0\r\n",
"547,Long,False,0,0\r\n",
"548,Long,False,0,0\r\n",
"ExposureProgram,Short,False,0,Unknown\r\n",
"ISOSpeedRatings,Short,True,System.UInt16[],100\r\n",
"SensitivityType,Short,False,0,0\r\n",
"RecommendedExposureIndex,Long,False,0,0\r\n",
"ExifVersion,Undefined,True,System.Byte[],0220\r\n",
"ComponentsConfiguration,Undefined,True,System.Byte[],\"Y, Cb, Cr, -\"\r\n",
"MeteringMode,Short,False,2,\"Center Weighted Average\"\r\n",
"LightSource,Short,False,255,Unknown\r\n",
"Flash,Short,False,0,\"Not fired\"\r\n",
"SubsecTime,Ascii,False,503,503\r\n",
"SubsecTimeOriginal,Ascii,False,503,503\r\n",
"SubsecTimeDigitized,Ascii,False,503,503\r\n",
"FlashpixVersion,Undefined,True,System.Byte[],\"48 49 48 48\"\r\n",
"ColorSpace,Short,False,1,1\r\n",
"PixelXDimension,Short,False,4000,4000\r\n",
"PixelYDimension,Short,False,1800,1800\r\n",
"InteroperabilityIFD,Long,False,3891,3891\r\n",
"SensingMethod,Short,False,1,1\r\n",
"SceneType,Undefined,False,1,1\r\n",
"ExposureMode,Short,False,0,Auto\r\n",
"WhiteBalance,Short,False,0,Auto\r\n",
"FocalLengthIn35mmFilm,Short,False,0,0\r\n",
"SceneCaptureType,Short,False,0,Standard\r\n",
"GPSVersionID,Byte,True,System.Byte[],\"2 2 0 0\"\r\n",
"GPSLatitudeRef,Ascii,False,N,N\r\n",
"GPSLongitudeRef,Ascii,False,E,E\r\n",
"GPSAltitudeRef,Byte,False,0,0\r\n",
"ImageDescription,Ascii,False,,\r\n",
"Make,Ascii,False,motorola,motorola\r\n",
"Model,Ascii,False,\"motorola edge 20 lite\",\"motorola edge 20 lite\"\r\n",
"XResolution,Rational,False,72,72\r\n",
"YResolution,Rational,False,72,72\r\n",
"Software,Ascii,False,,\r\n",
"DateTime,Ascii,False,\"2025:06:27 15:57:16\",\"2025:06:27 15:57:16\"\r\n",
"549,Ascii,False,,\r\n",
"ExposureTime,Rational,False,5230/1000000,5230/1000000\r\n",
"FNumber,Rational,False,1900/1000,1.9\r\n",
"DateTimeOriginal,Ascii,False,\"2025:06:27 15:57:16\",2025-06-27T15:57:16\r\n",
"DateTimeDigitized,Ascii,False,\"2025:06:27 15:57:16\",2025-06-27T15:57:16\r\n",
"ShutterSpeedValue,SignedRational,False,5230/1000000,5230/1000000\r\n",
"ApertureValue,Rational,False,1900/1000,1900/1000\r\n",
"BrightnessValue,SignedRational,False,0/10,0/10\r\n",
"ExposureBiasValue,SignedRational,False,0/10,0/10\r\n",
"MaxApertureValue,Rational,False,0/100,0/100\r\n",
"FocalLength,Rational,False,5880/1000,5880/1000\r\n",
"MakerNote,Undefined,True,System.Byte[],\"77 79 84 0 1 1 1 1 77 0 0 85 2 0 128 0 0 0 170 3 0 0 2 85 1 0 1 0 0 0 83 0 0 0 3 85 1 0 1 0 0 0 28 0 0 0 17 85 9 0 1 0 0 0 201 1 0 0 18 85 4 0 1 0 0 0 0 0 0 0 32 85 4 0 1 0 0 0 2 0 0 0 49 85 3 0 1 0 0 0 4 0 0 0 64 85 1 0 1 0 0 0 95 0 0 0 80 85 1 0 1 0 0 0 95 0 0 0 97 85 3 0 1 0 0 0 1 0 0 0 229 85 4 0 1 0 0 0 1 1 0 0 230 85 4 0 1 0 0 0 66 3 0 0 231 85 4 0 1 0 0 0 1 1 0 0 232 85 4 0 1 0 0 0 66 3 0 0 233 85 2 0 40 0 0 0 42 4 0 0 0 96 9 0 1 0 0 0 0 0 0 0 0 100 2 0 5 0 0 0 82 4 0 0 16 100 2 0 3 0 0 0 78 79 0 0 32 100 2 0 23 0 0 0 87 4 0 0 51 100 2 0 2 0 0 0 48 0 0 0 52 100 2 0 2 0 0 0 48 0 0 0 81 100 2 0 4 0 0 0 48 46 56 0 92 100 2 0 5 0 0 0 110 4 0 0 192 100 2 0 7 0 0 0 115 4 0 0 193 100 2 0 22 0 0 0 122 4 0 0 194 100 2 0 6 0 0 0 144 4 0 0 208 100 2 0 30 0 0 0 150 4 0 0 18 102 3 0 1 0 0 0 0 0 0 0 19 102 3 0 1 0 0 0 0 0 0 0 20 102 3 0 1 0 0 0 0 0 0 0 21 102 3 0 1 0 0 0 0 0 0 0 64 102 2 0 40 0 0 0 180 4 0 0 66 102 3 0 1 0 0 0 0 0 0 0 67 102 3 0 1 0 0 0 0 0 0 0 68 102 3 0 1 0 0 0 0 0 0 0 69 102 3 0 1 0 0 0 0 0 0 0 79 102 3 0 1 0 0 0 64 0 0 0 80 102 3 0 1 0 0 0 64 0 0 0 81 102 3 0 1 0 0 0 64 0 0 0 82 102 3 0 1 0 0 0 64 0 0 0 84 102 3 0 1 0 0 0 0 0 0 0 85 102 3 0 1 0 0 0 0 0 0 0 86 102 3 0 1 0 0 0 0 0 0 0 94 102 2 0 40 0 0 0 220 4 0 0 95 102 9 0 1 0 0 0 0 0 0 0 96 102 3 0 1 0 0 0 0 0 0 0 97 102 3 0 1 0 0 0 0 0 0 0 99 102 3 0 1 0 0 0 0 0 0 0 100 102 3 0 1 0 0 0 0 0 0 0 103 102 2 0 10 0 0 0 4 5 0 0 104 102 2 0 7 0 0 0 14 5 0 0 105 102 2 0 10 0 0 0 21 5 0 0 255 102 3 0 1 0 0 0 3 0 0 0 0 103 2 0 40 0 0 0 31 5 0 0 1 103 2 0 40 0 0 0 71 5 0 0 2 103 2 0 40 0 0 0 111 5 0 0 3 103 2 0 40 0 0 0 151 5 0 0 4 103 2 0 40 0 0 0 191 5 0 0 5 103 2 0 40 0 0 0 231 5 0 0 6 103 2 0 1 0 0 0 52 57 0 0 0 112 1 0 1 0 0 0 0 0 0 0 1 112 3 0 1 0 0 0 236 4 0 0 2 112 3 0 1 0 0 0 162 3 0 0 3 112 3 0 1 0 0 0 198 5 0 0 4 112 3 0 1 0 0 0 114 4 0 0 14 113 2 0 7 0 0 0 15 6 0 0 15 113 2 0 30 0 0 0 22 6 0 0 16 113 2 0 22 0 0 0 52 6 0 0 20 113 2 0 17 0 0 0 74 6 0 0 23 113 2 0 5 0 0 0 91 6 0 0 24 113 2 0 5 0 0 0 96 6 0 0 25 113 9 0 1 0 0 0 0 0 0 0 26 113 2 0 10 0 0 0 101 6 0 0 64 113 9 0 1 0 0 0 0 0 81 22 145 113 1 0 1 0 0 0 0 0 0 0 146 113 2 0 4 0 0 0 79 70 70 0 150 113 2 0 3 0 0 0 78 79 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 68 111 110 103 119 111 111 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 65 85 84 79 0 83 99 101 110 101 58 32 72 65 76 95 70 82 65 77 69 95 83 84 65 67 75 0 78 79 78 69 0 53 52 54 52 59 32 0 49 46 54 54 54 48 50 44 32 49 44 32 49 46 53 53 50 55 51 59 32 0 48 120 50 59 32 0 72 65 76 45 70 114 97 109 101 45 83 116 97 99 107 45 83 116 97 116 101 45 77 97 99 104 105 110 101 0 48 120 51 50 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 109 111 116 95 115 53 107 104 109 50 95 109 105 112 105 95 114 97 119 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 57 46 49 46 49 56 46 57 50 0 50 46 48 46 56 49 0 48 53 46 49 48 46 48 50 49 0 48 52 98 51 53 101 57 101 51 53 100 56 102 102 102 102 102 102 102 102 102 102 102 102 102 102 102 102 102 102 102 102 0 0 0 0 0 0 0 0 83 67 50 56 67 57 57 54 56 54 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 83 117 110 110 121 115 32 51 57 51 57 48 65 45 52 48 48 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 79 70 105 108 109 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 78 67 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 50 48 50 49 47 49 49 47 50 52 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 51 54 49 49 59 32 0 57 54 48 51 49 57 48 52 48 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 40 115 116 97 116 101 58 112 111 115 41 58 32 50 58 48 46 55 57 54 57 0 51 48 52 49 52 49 55 55 53 55 48 48 48 48 48 48 0 78 79 78 69 0 78 79 78 69 0 54 54 46 57 48 49 50 59 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\"\r\n",
"DigitalZoomRatio,Rational,False,100/100,100/100\r\n",
"GPSLatitude,Rational,True,SixLabors.ImageSharp.Rational[],50°4'46.4685\"\"\r\n",
"GPSLongitude,Rational,True,SixLabors.ImageSharp.Rational[],14°37'42.775\"\"\r\n",
"GPSAltitude,Rational,False,0,0\r\n",
"GPSTimestamp,Rational,True,SixLabors.ImageSharp.Rational[],\"13 57 16\"\r\n",
"GPSProcessingMethod,Undefined,False,CELLID\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000,CELLID\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\r\n",
"GPSDateStamp,Ascii,False,2025:06:27,2025:06:27\r\n"
],
"text/html": [
"<table><thead><tr><td><span>Tag</span></td><td><span>Type</span></td><td><span>IsArray</span></td><td><span>RawValue</span></td><td><span>FormattedValue</span></td></tr></thead><tbody><tr><td>ImageWidth</td><td><span>Short</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><details class=\"dni-treeview\"><summary><span class=\"dni-code-hint\"><code>4000</code></span></summary><div><table><thead><tr></tr></thead><tbody></tbody></table></div></details></td><td>4000</td></tr><tr><td>ImageLength</td><td><span>Short</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><details class=\"dni-treeview\"><summary><span class=\"dni-code-hint\"><code>1800</code></span></summary><div><table><thead><tr></tr></thead><tbody></tbody></table></div></details></td><td>1800</td></tr><tr><td>Orientation</td><td><span>Short</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>1</pre></div></td><td>Top Left</td></tr><tr><td>ResolutionUnit</td><td><span>Short</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>2</pre></div></td><td>2</td></tr><tr><td>YCbCrPositioning</td><td><span>Short</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>2</pre></div></td><td>2</td></tr><tr><td>544</td><td><span>Long</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>0</pre></div></td><td>0</td></tr><tr><td>545</td><td><span>Long</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>0</pre></div></td><td>0</td></tr><tr><td>546</td><td><span>Long</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>0</pre></div></td><td>0</td></tr><tr><td>547</td><td><span>Long</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>0</pre></div></td><td>0</td></tr><tr><td>548</td><td><span>Long</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>0</pre></div></td><td>0</td></tr><tr><td>ExposureProgram</td><td><span>Short</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>0</pre></div></td><td>Unknown</td></tr><tr><td>ISOSpeedRatings</td><td><span>Short</span></td><td><div class=\"dni-plaintext\"><pre>True</pre></div></td><td><div class=\"dni-plaintext\"><pre>[ 100 ]</pre></div></td><td>100</td></tr><tr><td>SensitivityType</td><td><span>Short</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>0</pre></div></td><td>0</td></tr><tr><td>RecommendedExposureIndex</td><td><span>Long</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>0</pre></div></td><td>0</td></tr><tr><td>ExifVersion</td><td><span>Undefined</span></td><td><div class=\"dni-plaintext\"><pre>True</pre></div></td><td><div class=\"dni-plaintext\"><pre>[ 48, 50, 50, 48 ]</pre></div></td><td>0220</td></tr><tr><td>ComponentsConfiguration</td><td><span>Undefined</span></td><td><div class=\"dni-plaintext\"><pre>True</pre></div></td><td><div class=\"dni-plaintext\"><pre>[ 1, 2, 3, 0 ]</pre></div></td><td>Y, Cb, Cr, -</td></tr><tr><td>MeteringMode</td><td><span>Short</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>2</pre></div></td><td>Center Weighted Average</td></tr><tr><td>LightSource</td><td><span>Short</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>255</pre></div></td><td>Unknown</td></tr><tr><td>Flash</td><td><span>Short</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td><div class=\"dni-plaintext\"><pre>0</pre></div></td><td>Not fired</td></tr><tr><td>SubsecTime</td><td><span>Ascii</span></td><td><div class=\"dni-plaintext\"><pre>False</pre></div></td><td>503</td><td>503</td></tr><tr><td colspan=\"5\"><i>(43 more)</i></td></tr></tbody></table><style>\r\n",
".dni-code-hint {\r\n",
" font-style: italic;\r\n",
" overflow: hidden;\r\n",
" white-space: nowrap;\r\n",
"}\r\n",
".dni-treeview {\r\n",
" white-space: nowrap;\r\n",
"}\r\n",
".dni-treeview td {\r\n",
" vertical-align: top;\r\n",
" text-align: start;\r\n",
"}\r\n",
"details.dni-treeview {\r\n",
" padding-left: 1em;\r\n",
"}\r\n",
"table td {\r\n",
" text-align: start;\r\n",
"}\r\n",
"table tr { \r\n",
" vertical-align: top; \r\n",
" margin: 0em 0px;\r\n",
"}\r\n",
"table tr td pre \r\n",
"{ \r\n",
" vertical-align: top !important; \r\n",
" margin: 0em 0px !important;\r\n",
"} \r\n",
"table th {\r\n",
" text-align: start;\r\n",
"}\r\n",
"</style>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"public static string ToPrettyString(IExifValue exif) {\n",
"\n",
" static string GetLabel(object value, string labels) {\n",
" var labelArray = labels.Split(',').Select(s => s.Trim()).ToArray();\n",
" var index = (ushort)value;\n",
" return index < 0 || index >= labelArray.LongLength ? labelArray[0] : labelArray[index];\n",
" }\n",
"\n",
" static IEnumerable<string> GetFlashFlags(object value) {\n",
" var flags = (ushort)value;\n",
" yield return (flags & 1) != 0 ? \"Fired\" : \"Not fired\";\n",
" if ((flags & 2) != 0) yield return \"Strobe return light detected\";\n",
" if ((flags & 4) != 0) yield return \"Strobe return light not detected\";\n",
" if ((flags & 8) != 0) yield return \"Compulsory flash mode\";\n",
" if ((flags & 16) != 0) yield return \"Auto mode\";\n",
" if ((flags & 32) != 0) yield return \"No flash function\";\n",
" if ((flags & 64) != 0) yield return \"Red eye reduction mode\";\n",
" }\n",
"\n",
" static string GetGpsCoordinate(object value) {\n",
" try {\n",
" var array = value as Rational[];\n",
" return $\"{array[0]}°{array[1]}'{System.Xml.XmlConvert.ToString(array[2].ToDouble())}\\\"\";\n",
" } catch (Exception) {\n",
" return null;\n",
" }\n",
" }\n",
"\n",
" // Special cases\n",
" if (exif.Tag == ExifTag.Orientation) return GetLabel(exif.GetValue(), \"Unknown, Top Left, Top Right, Bottom Right, Bottom Left, Left Top, Right Top, Right Bottom, Left Bottom\");\n",
" if (exif.Tag == ExifTag.ExposureProgram) return GetLabel(exif.GetValue(), \"Unknown, Manual, Auto, Aperture priority, Shutter speed priority, Creative, Action, Portrait, Landscape, Bulb\");\n",
" if (exif.Tag == ExifTag.MeteringMode) return GetLabel(exif.GetValue(), \"Unknown, Average, Center Weighted Average, Spot, Multi Spot, Multi Segment, Partial\");\n",
" if (exif.Tag == ExifTag.LightSource) return GetLabel(exif.GetValue(), \"Unknown, Daylight, Fluorescent, Tungsten, Flash, Sunny, Cloudy, Shade, Daylight Fluorescent, Day White Fluorescent, Cool White Fluorescent, White Fluorescent, Warm White Fluorescent, Standard Light A, Standard Light B, StandardLight C, D55, D65, D75, D50, ISO Studio Tungsten\");\n",
" if (exif.Tag == ExifTag.ExposureMode) return GetLabel(exif.GetValue(), \"Auto, Manual, Auto bracket\");\n",
" if (exif.Tag == ExifTag.WhiteBalance) return GetLabel(exif.GetValue(), \"Auto, Manual\");\n",
" if (exif.Tag == ExifTag.FNumber) return ((Rational)exif.GetValue()).ToDouble().ToString(\"N1\", System.Globalization.CultureInfo.InvariantCulture);\n",
" if (exif.Tag == ExifTag.SceneCaptureType) return GetLabel(exif.GetValue(), \"Standard, Landscape, Portrait, Night, Other\");\n",
" if (exif.Tag == ExifTag.DateTimeOriginal || exif.Tag == ExifTag.DateTimeDigitized) return DateTime.TryParseExact(exif.GetValue().ToString(), @\"yyyy\\:MM\\:dd HH\\:mm\\:ss\", null, System.Globalization.DateTimeStyles.None, out var dt) ? System.Xml.XmlConvert.ToString(dt, System.Xml.XmlDateTimeSerializationMode.RoundtripKind) : null;\n",
" if (exif.Tag == ExifTag.Flash) return string.Join(\", \", GetFlashFlags(exif.GetValue()));\n",
" if (exif.Tag == ExifTag.GPSDestLatitude || exif.Tag == ExifTag.GPSDestLongitude || exif.Tag == ExifTag.GPSLatitude || exif.Tag == ExifTag.GPSLongitude) return GetGpsCoordinate(exif.GetValue());\n",
" if (exif.Tag == ExifTag.ExifVersion) return System.Text.Encoding.UTF8.GetString((byte[])exif.GetValue());\n",
" if (exif.Tag == ExifTag.ComponentsConfiguration) return string.Join(\", \", ((byte[])exif.GetValue()).Select(b => GetLabel((ushort)b, \"-, Y, Cb, Cr, R, G, B\")));\n",
"\n",
" // Array of generic values\n",
" if (exif.IsArray) {\n",
" var s = string.Empty;\n",
" foreach (var item in exif.GetValue() as Array) {\n",
" s += item.ToString() + \" \";\n",
" }\n",
" return s.Trim();\n",
" }\n",
"\n",
" // If no special case occurred, just return ToString()\n",
" return exif.GetValue().ToString();\n",
"}\n",
"\n",
"// Use the helper method to display data\n",
"using (Image image = Image.Load(imageFileName)) {\n",
" var exifProfile = image.Metadata.ExifProfile;\n",
" if (exifProfile != null) {\n",
" var results = exifProfile.Values.Select(p=> new {\n",
" Tag = p.Tag.ToString(),\n",
" Type = p.DataType,\n",
" IsArray = p.IsArray,\n",
" RawValue = p.GetValue(),\n",
" FormattedValue = ToPrettyString(p),\n",
" });\n",
" results.DisplayTable();\n",
" } else {\n",
" Console.WriteLine(\"No EXIF metadata found.\");\n",
" }\n",
"}"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".NET (C#)",
"language": "C#",
"name": ".net-csharp"
},
"language_info": {
"name": "polyglot-notebook"
},
"polyglot_notebook": {
"kernelInfo": {
"defaultKernelName": "csharp",
"items": [
{
"aliases": [],
"languageName": "csharp",
"name": "csharp"
}
]
}
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment