I want to "correct" the orientation of an image. My plan is to extract the orientation from the Exif data stored with the image and use that to inform a re-orientation of the image.
It's probably me, but for this particular Exif property, the GetDescription (or GetString) simply returns null; all other properties that I have tried (x15) return a value. In the sample code below (a Console App), "Approach 1" uses the preferred and efficient GetDescription
approach to grab the image Orientation, while "Approach 2" uses an inefficient foreach
loop to iterate through directories and tags searching for the Orientation.
using MetadataExtractor;
using MetadataExtractor.Formats.Exif;
string Filename = @"D:\Users\Simon\OneDrive\My Stuff\My Source\TestFuelPriceTracker\Originals\IMG_8490.jpg";
IEnumerable<MetadataExtractor.Directory> directories = ImageMetadataReader.ReadMetadata(Filename);
// Approach 1
var subIfdDirectory = directories.OfType<ExifSubIfdDirectory>().FirstOrDefault();
var Orientation1 = subIfdDirectory?.GetDescription(ExifDirectoryBase.TagOrientation);
Console.WriteLine($"Approach 1: Orientation = \"{Orientation1}\"");
// Approach 2
foreach (var directory in directories)
{
foreach (var tag in directory.Tags)
{
switch (tag.Name)
{
case "Orientation":
Console.WriteLine($"Approach 2: Orientation = \"{tag.Description}\"");
break;
}
}
}
// Approach 3
var Orientation2 = directories
.OfType<ExifSubIfdDirectory>()
.FirstOrDefault(s => string.Equals(s?.GetDescription(ExifDirectoryBase.TagOrientation), "Orientation", StringComparison.OrdinalIgnoreCase));
Console.WriteLine($"Approach 3: Orientation = \"{Orientation2}\"");
When run, I get the following results...
Approach 1: Orientation = ""
Approach 2: Orientation = "Top, left side (Horizontal / normal)"
Approach 3: Orientation = ""
Approach 2 shows that the Orientation information is actually present in the image. Please note that I have tried numerous images and I get the same problem. Not sure if this is relevant, but all images were taken on an iPhone 12.
Approach 3 added based on a suggestion by @aybe.
I am using Visual Studio 2022 on a Windows 11 Professional machine, all software patched to latest versions. The framework is .NET 6. MetadataExtractor version 2.7.2.
Proposed final solution is...
IEnumerable<MetadataExtractor.Directory> directories = ImageMetadataReader.ReadMetadata(Filename);
var ifd0Directory = directories.OfType<ExifIfd0Directory>().FirstOrDefault();
int Orientation = -1;
if (ifd0Directory != null) {
Orientation = ifd0Directory.TryGetInt32(ExifDirectoryBase.TagOrientation, out int value) ? value : -1;
}
If successful it returns an integer value from 1 to 8 inclusive, or -1 if there is a problem. For anyone whose interested, the meaning of these numbers is discussed well in the following article...
JPEG Image Orientation and Exif
I would also point you at the following MIT paper which has captured the data types for each of the Exif tags; along with a lot of other good information too...