目标
我想“纠正”一个图像的方向。我的计划是从与图像一起存储的Exif数据中提取方向,并使用它通知图像的重新定向。
问题
可能是我,但对于这个特定的Exif属性,GetDescription (或GetString)只返回null;我尝试过的所有其他属性(x15)都返回一个值。在下面的示例代码(控制台应用程序)中,“方法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上拍摄的。
方法3是根据@aybe的建议添加的。
环境
我在Windows 11专业计算机上使用Visual 2022,所有软件都修补成最新版本。该框架是.NET 6. MetadataExtractor版本2.7.2。
发布于 2022-03-26 20:38:05
建议的最终解决方案是..。
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;
}如果成功,它将返回一个整数值,从1到8(含),或者-1 (如果有问题)。对于任何感兴趣的人,这些数字的含义将在下面的文章中详细讨论.
我还要指出以下麻省理工学院的论文,它捕获了每个Exif标签的数据类型;还有许多其他的好信息.
发布于 2022-03-26 15:12:46
您的代码将永远无法工作,因为它比较了标记的整数值,这当然永远不会与"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;
}https://stackoverflow.com/questions/71628565
复制相似问题