77

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

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

4

8 回答 8

49

正如建议的那样,您可以使用一些 3rd 方库,或者手动执行(这不是很多工作),但最简单和最灵活的可能是使用 .NET 中的内置功能。有关更多信息,请参阅:

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

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


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

于 2009-08-12T21:34:19.207 回答
23

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


EDIT 元数据提取器也支持 .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);

它可以通过NuGetGitHub 上的代码获得

于 2008-10-01T08:00:51.110 回答
9

这是另一个类似 SO question的链接,该问题的答案指向.Net中关于“阅读、写作和照片元数据”的这篇好文章。

于 2009-03-11T22:24:46.810 回答
9

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

我也喜欢ExifUtils API,但它有问题并且没有积极开发。

于 2011-10-25T09:21:19.293 回答
6

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

于 2008-09-12T10:53:06.130 回答
4

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

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

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

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

于 2012-02-03T02:43:06.433 回答
0

最近,我使用了这个.NET Metadata API。我还写了一篇关于它的博客文章,展示了使用 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);
     }
}
于 2020-08-11T05:32:29.243 回答