簡體   English   中英

從 C# 中的 JPEG、XMP 或 EXIF 讀取數據元數據

[英]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);

該庫還通過 Adob​​e 的 XmpCore Java 庫的 C# 端口支持 XMP 數據。

https://github.com/drewnoakes/xmp-core-dotnet

如果您正在為 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 元數據策略來查找值是否存在。

如果您嘗試訪問這些屬性:

在此處輸入圖像描述

您可以執行以下操作:

  1. 添加對 C:\Windows\System32\Shell32.dll 的引用。 VS 2022 自動創建一個互操作來與 ActiveX 庫進行交互。
  2. 我將以下代碼添加到按鈕單擊事件中,以演示獲取所需數據。

代碼示例:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM