使用 MetadataExtractor GetDescription 获取方向时出现问题
Problem obtaining Orientation using MetadataExtractor GetDescription
Objective
我想“纠正”图像的方向。我的计划是从与图像一起存储的 Exif 数据中提取方向,并使用它来通知图像的重新定位。
问题
可能是我,但对于这个特定的 Exif 属性,GetDescription(或 GetString)只是 returns null;我尝试过的所有其他属性 (x15) return 一个值。在下面的示例代码(控制台应用程序)中,“方法 1”使用首选且高效的 GetDescription
方法来获取图像方向,而“方法 2”使用低效的 foreach
循环来遍历目录和搜索方向的标签。
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}\"");
当运行时,我得到以下结果...
Approach 1: Orientation = ""
Approach 2: Orientation = "Top, left side (Horizontal / normal)"
Approach 3: Orientation = ""
方法 2 表明方向信息实际上存在于图像中。请注意,我尝试了很多图像,但我遇到了同样的问题。不确定这是否相关,但所有图像都是在 iPhone 12.
上拍摄的
根据@aybe 的建议添加的方法 3。
环境
我在 Windows 11 Professional 机器上使用 Visual Studio 2022,所有软件都已修补到最新版本。框架是 .NET 6。MetadataExtractor 版本 2.7.2.
您的代码永远不会工作,因为它正在比较标签的整数值,这当然永远不会匹配 "Orientation"
。
这可行,但由于某些图像不一定具有我所说的标签,因此可能会失败,可能值得考虑从其他标签或图像尺寸计算方向作为后备解决方案。
private static void GetOrientation(Stream stream)
{
var directories = ImageMetadataReader.ReadMetadata(stream);
if (TryGetOrientationTag(directories, out var result))
{
}
else
{
throw new NotImplementedException("Compute orientation from image size instead");
}
}
private static bool TryGetOrientationTag(IEnumerable<Directory> directories, out string result)
{
result = null!;
foreach (var directory in directories)
{
switch (directory)
{
case ExifDirectoryBase e:
foreach (var tag in e.Tags)
{
if (tag.Type is not ExifDirectoryBase.TagOrientation || tag.Description is null)
continue;
result = tag.Description;
return true;
}
break;
case IptcDirectory i:
foreach (var tag in i.Tags)
{
if (tag.Type is not IptcDirectory.TagImageOrientation || tag.Description is null)
continue;
result = tag.Description;
return true;
}
break;
}
}
return false;
}
建议的最终解决方案是...
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;
}
如果成功,它 returns 一个从 1 到 8 的整数值,如果有问题,则为 -1。对于任何感兴趣的人,这些数字的含义将在以下文章中详细讨论...
JPEG Image Orientation and Exif
我还会向您指出以下麻省理工学院的论文,其中捕获了每个 Exif 标签的数据类型;还有很多其他有用的信息...
Objective
我想“纠正”图像的方向。我的计划是从与图像一起存储的 Exif 数据中提取方向,并使用它来通知图像的重新定位。
问题
可能是我,但对于这个特定的 Exif 属性,GetDescription(或 GetString)只是 returns null;我尝试过的所有其他属性 (x15) return 一个值。在下面的示例代码(控制台应用程序)中,“方法 1”使用首选且高效的 GetDescription
方法来获取图像方向,而“方法 2”使用低效的 foreach
循环来遍历目录和搜索方向的标签。
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}\"");
当运行时,我得到以下结果...
Approach 1: Orientation = ""
Approach 2: Orientation = "Top, left side (Horizontal / normal)"
Approach 3: Orientation = ""
方法 2 表明方向信息实际上存在于图像中。请注意,我尝试了很多图像,但我遇到了同样的问题。不确定这是否相关,但所有图像都是在 iPhone 12.
上拍摄的根据@aybe 的建议添加的方法 3。
环境
我在 Windows 11 Professional 机器上使用 Visual Studio 2022,所有软件都已修补到最新版本。框架是 .NET 6。MetadataExtractor 版本 2.7.2.
您的代码永远不会工作,因为它正在比较标签的整数值,这当然永远不会匹配 "Orientation"
。
这可行,但由于某些图像不一定具有我所说的标签,因此可能会失败,可能值得考虑从其他标签或图像尺寸计算方向作为后备解决方案。
private static void GetOrientation(Stream stream)
{
var directories = ImageMetadataReader.ReadMetadata(stream);
if (TryGetOrientationTag(directories, out var result))
{
}
else
{
throw new NotImplementedException("Compute orientation from image size instead");
}
}
private static bool TryGetOrientationTag(IEnumerable<Directory> directories, out string result)
{
result = null!;
foreach (var directory in directories)
{
switch (directory)
{
case ExifDirectoryBase e:
foreach (var tag in e.Tags)
{
if (tag.Type is not ExifDirectoryBase.TagOrientation || tag.Description is null)
continue;
result = tag.Description;
return true;
}
break;
case IptcDirectory i:
foreach (var tag in i.Tags)
{
if (tag.Type is not IptcDirectory.TagImageOrientation || tag.Description is null)
continue;
result = tag.Description;
return true;
}
break;
}
}
return false;
}
建议的最终解决方案是...
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;
}
如果成功,它 returns 一个从 1 到 8 的整数值,如果有问题,则为 -1。对于任何感兴趣的人,这些数字的含义将在以下文章中详细讨论...
JPEG Image Orientation and Exif
我还会向您指出以下麻省理工学院的论文,其中捕获了每个 Exif 标签的数据类型;还有很多其他有用的信息...