【问题标题】:How to get the EXIF data from a file using C#如何使用 C# 从文件中获取 EXIF 数据
【发布时间】:2010-09-08 16:31:58
【问题描述】:

我想用 C# 编写一个小程序,它会检查我的 jpeg 照片,例如,将它们分类到过时的文件夹中(使用我的约会约定,该死的......)。

有没有人知道以编程方式获取 EXIF 数据(例如日期和时间)或曝光的相对简单的方法? 谢谢!

【问题讨论】:

  • BCL 对图像元数据的内置支持非常有限。自 2002 年以来,我一直在使用诸如 Exif 之类的元数据,并且拥有一个简单而强大的 library for extracting such data for .NET
  • 为什么关闭?它确实专注于一个问题,即从文件中获取 EXIT。还有一个明确而有针对性的答案。

标签: c# exif photography


【解决方案1】:

按照建议,您可以使用一些 3rd 方库,或者手动执行(这不是很多工作),但最简单和最灵活的可能是使用 .NET 中的内置功能。更多请看:

我说“它是最灵活的”,因为 .NET 不会尝试以任何方式解释或合并数据。对于每个 EXIF,您基本上都会得到一个字节数组。这可能是好是坏,取决于您实际想要多少控制。

另外,我应该指出,属性列表实际上并不直接对应于 EXIF 值。 EXIF 本身存储在具有重叠 ID 的多个表中,但 .NET 将所有内容放在一个列表中并重新定义某些项目的 ID。但只要您不关心精确的 EXIF ID,您应该可以使用 .NET 映射。


编辑:可以在不加载完整图像的情况下执行此答案:https://stackoverflow.com/a/552642/2097240

【讨论】:

  • 访问 Bitmap.PropertyItems 需要将整个文件读入内存。如果您创建一个位图、访问 PropertyItems 并且不执行任何其他操作,则可以使用 XPerf 查看您的应用程序访问了图像文件并将其全部读入内存。对于我的电脑,一个 3.4mb 的文件花费 >700ms 的 IO,只是为了通过 PropertyItems 获取 EXIF :(.
  • 相比之下,Picasa 的 PhotoViewer 从它接触的每个文件中仅读取 20 - 30k。这些读取只需约 25 毫秒。哇;我很想和写那些东西的男人/女孩聊天。 (数据是通过使用 XPerf 分析 PhotoViewer 的启动来收集的)。
  • @Tristan:有用的信息,但是您多久访问一次图像元数据而不需要图像本身?我相信在某些情况下,但我认为在大多数情况下,一个人会同时显示图像(或以其他方式使用它的数据)和它的元数据。
  • @jrista 我多久需要一次元数据?大多数时候。例如,假设您想通过一条元数据对一组图像进行排序或过滤。按拍摄日期排序是很常见的事情,要获取该信息,您必须进入元数据。
  • 这个答案展示了如何使用PropertyItems 不加载整个图像stackoverflow.com/a/552642
【解决方案2】:

看看这个metadata extractor它是用 Java 编写的,但也被移植到了 C#。 我使用 Java 版本编写了一个小实用程序来根据日期和模型标签重命名我的 jpeg 文件。非常容易使用。


EDIT metadata-extractor 也支持 .NET。这是一个非常快速和简单的库,用于从图像和视频中访问元数据。

它完全支持 Exif,以及 IPTC、XMP 和许多其他类型的元数据,包括 JPEG、PNG、GIF、PNG、ICO、WebP、PSD 等文件类型。

var directories = ImageMetadataReader.ReadMetadata(imagePath);

// print out all metadata
foreach (var directory in directories)
foreach (var tag in directory.Tags)
    Console.WriteLine($"{directory.Name} - {tag.Name} = {tag.Description}");

// access the date time
var subIfdDirectory = directories.OfType<ExifSubIfdDirectory>().FirstOrDefault();
var dateTime = subIfdDirectory?.GetDateTime(ExifDirectoryBase.TagDateTime);

可通过NuGetcode's on GitHub 获得。

【讨论】:

  • 如果您的 Windows 应用程序总是将 iPhone 图像横向或上下颠倒显示,那就太好了。每个图像中都有一个Orientation 标签,通常是一个幻数,但这个库会告诉你旋转(即Rotate 180Rotate 90 CCW)。
【解决方案3】:

这里是另一个similar SO question 的链接,其中的答案指向.Net 中"Reading, writing and photo metadata" 上的这篇好文章。

【讨论】:

【解决方案4】:

您可以使用TagLib#,它被F-Spot 等应用程序使用。除了 Exif,它还能读取大量的图像、音频和视频元数据格式。

我也喜欢ExifUtils API,但它有缺陷且没有积极开发。

【讨论】:

    【解决方案5】:

    Image 类具有 PropertyItems 和 PropertyIdList 属性。你可以使用它们。

    【讨论】:

    • 它好像是只读的,所以我不能在新图像上添加任何内容...
    • 对新图像使用 Image.SetPropertyItem(PropertyItem) 函数。
    【解决方案6】:

    从 JPEG 图像中获取 EXIF 数据包括:

    1. 寻找提到EXIF数据开头的JPEG标记。例如通常 oxFFE1 是在编码 EXIF 数据时插入的标记,它是 EXIF 数据所在的应用程序段。
    2. 解析从 0xFFE1 到 0xFFE2 的所有数据。此数据将是 JPEG 编码文件中的字节流。
    3. 这些字节的 ASCII 等价物将包含与图像日期、相机型号名称、曝光等相关的各种信息...

    【讨论】:

      【解决方案7】:

      命令行工具ExifTool by Phil Harvey 可处理数十种图像格式(包括大量专有的 RAW 格式),并且可以处理各种元数据格式,包括 EXIF、GPS、IPTC、XMP、JFIF。

      非常易于使用、轻量级、令人印象深刻的应用程序。

      【讨论】:

      • ExifTool 是一个了不起的库/工具,但它是用 Perl 编写的,因此在 C# 中使用它需要启动一个外部进程。
      【解决方案8】:

      最近,我使用了这个.NET Metadata API。我还写了一个关于它的blog post,它显示了使用 C# 从图像中读取、更新和删除 EXIF 数据。

      using (Metadata metadata = new Metadata("image.jpg"))
      {
          IExif root = metadata.GetRootPackage() as IExif;
          if (root != null && root.ExifPackage != null)
          {
              Console.WriteLine(root.ExifPackage.DateTime);
           }
      }
      

      【讨论】:

        猜你喜欢
        • 2018-10-03
        • 1970-01-01
        • 2021-09-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多