[英]Reading data metadata from JPEG, XMP or EXIF in C#
我一直在寻找一种从 C# 中的 JPEG 文件中读取元数据(特别是拍摄日期)的体面方法,但我发现有点短。 据我所知,现有信息显示如下代码;
BitmapMetadata bmd = (BitmapMetadata)frame.Metadata;
string a1 = (string)bmd.GetQuery("/app1/ifd/exif:{uint=36867}");
但在我的无知中,我不知道 GetQuery() 将返回什么元数据,或者传递什么。
我想先尝试读取 XMP,如果 XMP 不存在则回退到 EXIF。 有没有一种简单的方法可以做到这一点?
谢谢。
以下似乎工作得很好,但如果有什么不好的地方,我会很感激任何评论。
public string GetDate(FileInfo f)
{
using(FileStream fs = new FileStream(f.FullName, FileMode.Open, FileAccess.Read, FileShare.Read))
{
BitmapSource img = BitmapFrame.Create(fs);
BitmapMetadata md = (BitmapMetadata)img.Metadata;
string date = md.DateTaken;
Console.WriteLine(date);
return date;
}
}
我最近将我的长期开源 Java 库移植到了 .NET,它支持 XMP、Exif、ICC、JFIF 和多种图像格式的更多类型的元数据。 它一定会实现你所追求的。
https://github.com/drewnoakes/metadata-extractor-dotnet
var directories = ImageMetadataReader.ReadMetadata(imagePath);
var subIfdDirectory = directories.OfType<ExifSubIfdDirectory>().FirstOrDefault();
var dateTime = subIfdDirectory?.GetDescription(ExifDirectoryBase.TagDateTime);
该库还通过 Adobe 的 XmpCore Java 库的 C# 端口支持 XMP 数据。
如果您正在为 XMP jn jpeg 苦苦挣扎,这很有效。 这不叫残忍!
public class BrutalXmp
{
public XmlDocument ExtractXmp(byte[] jpegBytes)
{
var asString = Encoding.UTF8.GetString(jpegBytes);
var start = asString.IndexOf("<x:xmpmeta");
var end = asString.IndexOf("</x:xmpmeta>") + 12;
if (start == -1 || end == -1)
return null;
var justTheMeta = asString.Substring(start, end - start);
var returnVal = new XmlDocument();
returnVal.LoadXml(justTheMeta);
return returnVal;
}
}
我认为您正在做的是一个很好的解决方案,因为 System.DateTaken 处理程序会自动应用回退到其他命名空间的Photo 元数据策略来查找值是否存在。
如果您尝试访问这些属性:
您可以执行以下操作:
代码示例:
Shell32.Shell shell = new Shell32.Shell();
Shell32.Shell objShell = shell.Application;
Shell32.Folder folder = objShell.NameSpace(@"D:\TestFolder");
Shell32.FolderItem folderItem = folder.ParseName("TestMetadata.jpg");
for (int tagIndex = 0; tagIndex < 321; tagIndex++)
{
// Pass null in the first parameter to get the tagName
string tagName = folder.GetDetailsOf(null, tagIndex);
if (!string.IsNullOrEmpty(tagName))
{
// Pass an instance of Shell32.FolderItem to get the tsg value.
string tagValue = folder.GetDetailsOf(folderItem, tagIndex);
Console.WriteLine($"[{tagIndex}] {tagName} = {tagValue}");
}
}
控制台将显示代表感兴趣值的字符串。 我不知道为什么,包含一位数月份和/或日期值的日期会显示一个? 为 0 位。 这些可以很容易地替换,然后可以解析日期。 下面是 output 的属性\详细信息选项卡中显示的一些有趣的:
[3] Date modified = 9/3/2022 2:37 PM
[4] Date created = 9/3/2022 2:35 PM
[5] Date accessed = 9/3/2022 10:38 PM
[12] Date taken = ?1/?1/?2022 ??2:36 PM
[18] Tags = Metadata Tags
[21] Title = My Test Title
[22] Subject = Being and Nothingness
[24] Comments = Kilroy wuz here!
[25] Copyright = 2022
[136] Date acquired = ?1/?2/?2022 ??2:36 PM
据我所知,有多达 320 种不同的标签类型。
我的公司制作了一个包含 XMP 和 EXIF 解析器的 .NET工具包。
典型的流程是这样的:
XmpParser parser = new XmpParser();
System.Xml.XmlDocument xml = (System.Xml.XmlDocument)parser.ParseFromImage(stream, frameIndex);
对于 EXIF,你会这样做:
ExitParser parser = new ExifParser();
ExifCollection exif = parser.ParseFromImage(stream, frameIndex);
显然,对于 JPEG,frameIndex 将为 0。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.