如何使用C#从文件获取EXIF数据


76

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

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


BCL对图像元数据的内置支持非常有限。自2002年以来,我一直在使用Exif等元数据,并且拥有一个简单但功能强大的库来为.NET提取此类数据
Drew Noakes

1
为什么关闭了?它确实关注一个问题,即从文件中退出。还有一个明确而集中的答案。
马夫

Answers:


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上代码获得


如果您的Windows应用始终显示iPhone图像横向或上下颠倒,那就太好了。Orientation每个图像中都有一个标记,通常是一个魔术数字,但是该库告诉您旋转(即Rotate 180Rotate 90 CCW)。
克里斯·阿奇里奇

47

如建议的那样,您可以使用某些第三方库,也可以手动进行(这不是很多工作),但是最简单,最灵活的方法是使用.NET中的内置功能。有关更多信息,请参见:

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

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


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


9
访问Bitmap.PropertyItems需要将整个文件读入内存。如果创建位图,访问PropertyItems而不执行其他任何操作,则可以使用XPerf来查看您的应用访问了图像文件并将其全部读取到内存中。对于我的计算机,一个3.4mb的文件花费了> 700ms的IO值,仅仅是为了通过PropertyItems获得EXIF :(。–
Tristan

4
相比之下,Picasa的PhotoViewer只能从其触摸的每个文件读取20-30k。这些读取仅花费〜25ms。哇; 我很想和写那个东西的男孩/女孩聊天。(通过使用XPerf对PhotoViewer的启动进行性能分析来收集数据)。
Tristan

@Tristan:有用的信息,但是,您在不想要图像本身的情况下多久访问一次图像元数据?我确定确实有一些情况,但是我认为在大多数情况下,将同时显示图像(或使用其数据)和元数据。
jrista

5
@jrista我多久才需要元数据?大多数时候。例如,假设您想通过一条元数据对一组图像进行排序或过滤。按日期排序是很常见的事情,要获取该信息,您必须进入元数据。
特里斯坦,

1
这个答案显示了如何在PropertyItems 不加载整个图像的情况下进行操作stackoverflow.com/a/552642
DanielMöller19年


8

您可以使用诸如F-Spot之类的应用程序使用的TagLib#。除了Exif之外,它将读取大量用于图像,音频和视频的元数据格式。

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



4

从JPEG图像获取EXIF数据涉及:

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

3

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

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


1
ExifTool是一个了不起的lib / tool,但是它是用Perl编写的,因此从C#使用它需要启动一个外部进程。
Drew Noakes

0

最近,我使用了.NET元数据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);
     }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.