【问题标题】:How to read keywords from an image file?如何从图像文件中读取关键字?
【发布时间】:2019-09-08 04:24:22
【问题描述】:

我想从图像文件中读取 ITPC 关键字。我想用它来检测我的约 20.000 张图像中是否有任何没有分配给它们的关键字。 此外,我想阅读图像的实际格式(jpeg、gif ...),无论它具有哪个扩展名。 额外的好处是我可以随时阅读尺寸和大小等其他信息。

我在网上找到了很多“解决方案”,但没有一个有效,或者速度非常慢。

例如,我尝试了这种“蛮力”解决方案:

byte[] image = File.ReadAllBytes(file.FullName);
var asString = Encoding.UTF8.GetString(image);
var start = asString.IndexOf("<x:xmpmeta");
var end = asString.IndexOf("</x:xmpmeta>") + 12;
if (start == -1 || end == -1 || end < start)
  return;
var justTheMeta = asString.Substring(start, end - start);
var returnVal = new XmlDocument();

但它太慢了,甚至无法等待它完成完全处理。而且我什至还没有完成代码(阅读实际的关键字)。

我最好的选择似乎是 Adob​​e XMP SDK 的 dotNET 包装器。 https://github.com/drewnoakes/xmp-core-dotnet

但是文档几乎不存在。我只能找到这个例子,但它不起作用,因为它似乎需要一个 XMP 文件,但我只有一个图像(gif、jpeg、png)文件。

IXmpMeta xmp;
using (var stream = File.OpenRead("some-file.xmp"))
    xmp = XmpMetaFactory.Parse(stream);

foreach (var property in xmp.Properties)
    Console.WriteLine($"Path={property.Path} Namespace={property.Namespace} Value={property.Value}");

我尝试这样做,但它在每张图像上都给我一个 XML 解析失败:

IXmpMeta xmp;
try
{
    byte[] image = File.ReadAllBytes(file.FullName);
    xmp = XmpMetaFactory.ParseFromBuffer(image);

    foreach (var property in xmp.Properties)
    Console.WriteLine($"Path={property.Path} Namespace={property.Namespace} Value={property.Value}");
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

我认为 XML 很好。我可以在 Notepad++ 中打开我的图像,然后我就可以在其中看到带有关键字的 XML。并且所有关键词在 ACDSee 和 Photoshop 等图像程序中都能很好地显示。

有人可以提供一个实际有效且相当高效的代码示例吗?我需要将其合并到我的 C# 程序中。

【问题讨论】:

  • 您需要以编程方式进行吗?如果没有,您可以使用exiftool。假设您指的是 IPTC Core 而不是 IPTC IIM,像 exiftool -Subject -FileType -ImageSize -FileSize &lt;DIR&gt; 这样的命令将读取并输出您提到的所有数据。此外,除了纯文本之外,输出还可以格式化为 CSV、JSON 或 XML 文件。
  • 我实际上确实需要以编程方式进行。它将是我正在构建的一个更大的应用程序的一部分,用于分析我的图像库。在 C# 中。

标签: c# image metadata keyword xmp


【解决方案1】:

您与 Drew Noakes XMP 库非常接近……您真正想要的是:https://github.com/drewnoakes/metadata-extractor-dotnet

代码如下所示:

   var metadata = ImageMetadataReader.ReadMetadata(imagePath);

   var IPTCdir = metadata.OfType<IptcDirectory>().FirstOrDefault();

   if (IPTCdir != null)
   {
      var caption = IPTCdir.SafeExifGetString(IptcDirectory.TagCaption);

      imgMetaData.Caption = FilteredDescription(caption);

      var keywordList = IPTCdir?.GetStringArray(IptcDirectory.TagKeywords);
   }

【讨论】:

    猜你喜欢
    • 2011-10-26
    • 1970-01-01
    • 2011-04-27
    • 1970-01-01
    • 1970-01-01
    • 2016-08-08
    • 1970-01-01
    • 2015-09-17
    • 2011-04-13
    相关资源
    最近更新 更多