在XMP dc:主题字段中存储数组

本文关键字:字段 存储 数组 XMP dc | 更新日期: 2023-09-27 18:19:20

我正在尝试复制Adobe Lightroom如何存储"关键字";在图像(JPEG)结构内。

到目前为止,我发现关键字存储在字段 的元数据中。

/xmp/dc:主题

Light room将每个标签存储为xml结构,格式为:

<dc:subject>
    <rdf:Bag>
        <rdf:li>Bianca</rdf:li>
        <rdf:li>KEYWORDS -LR</rdf:li>
        <rdf:li>Laura</rdf:li>
        <rdf:li>Lyndel</rdf:li>
        <rdf:li>T-ALL</rdf:li>
    </rdf:Bag>
</dc:subject>

我的问题是,当我用微软的元数据查询语言编写关键字时,关键字以字符串形式存储,因此在图像中关键字以格式存储:

<dc:subject>Bianca; KEYWORDS -LR; Laura; Lyndel; T-ALL</dc:subject>

所以,我的问题是如何存储和数组,使结果类似于上面的xml结构。

下面是我的代码:
// Read the image stream
using (var originalFile = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None))
{
    // Create the bitmap decoder
    decoder = BitmapDecoder.Create(originalFile, createOptions, BitmapCacheOption.None);
    // The the first frame contains the image metadata
    var bitmapFrame = decoder.Frames[0];
    if (bitmapFrame != null && bitmapFrame.Metadata != null)
    {
        // To be able to modify the metadata, first we need to clone it
        BitmapMetadata metadata = bitmapFrame.Metadata.Clone() as BitmapMetadata;
        // Remove the XP Subject field
        metadata.RemoveQuery("System.Subject");
        // Remove the XP keyword field
        metadata.RemoveQuery("System.Keywords");
        
        // Write Tags (Lightroom keywording)
        string keywords = "K1; K2; K3";
        metadata.SetQuery("/xmp/dc:Subject", keywords);
        
        // Create a bitmap encoder
        var encoder = CreateBitmapEncoder(imageFormat);
        // Create new frame with the updated metadata
        // Keep everything the same except the updated metadata
        encoder.Frames.Add(BitmapFrame.Create(
            bitmapFrame, bitmapFrame.Thumbnail, metadata, bitmapFrame.ColorContexts));
        // Attemp to save the update image
        using (Stream outputFile = File.Open(path + tempSufix, FileMode.Create, FileAccess.ReadWrite))
        {
            encoder.Save(outputFile);
        }
    }
}
编辑:

在这个链接https://msdn.microsoft.com/en-us/library/ee719963%28v=vs.85%29.aspx中,显示了写作应该在以下查询中:

/xmp/<xmpbag>dc:subject

但是<xmpbag>是什么呢?

Edit2:

结果是写"位置"如下:

/xmp/<xmpbag>dc:subject/{ulong=0}

/xmp/<xmpbag>dc:subject/{ulong=1}

在XMP dc:主题字段中存储数组

// Read the image stream
using (var originalFile = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None))
{
    // Create the bitmap decoder
    decoder = BitmapDecoder.Create(originalFile, createOptions, BitmapCacheOption.None);
    // The the first frame contains the image metadata
    var bitmapFrame = decoder.Frames[0];
    if (bitmapFrame != null && bitmapFrame.Metadata != null)
    {
        // To be able to modify the metadata, first we need to clone it
        BitmapMetadata metadata = bitmapFrame.Metadata.Clone() as BitmapMetadata;
        // Remove the XP Subject field
        metadata.RemoveQuery("System.Subject");
        // Remove the XP keyword field
        metadata.RemoveQuery("System.Keywords");
        // Write Tags (Lightroom keywording)
        var keywords = "K1; K2; K3";
        var keywordArray = keywords.Split(new[] { "; " }, StringSplitOptions.RemoveEmptyEntries);
        // Write in the XMP section
        metadata.SetQuery("/xmp/dc:Subject", new BitmapMetadata("xmpbag"));
        for (var i = 0; i < keywordArray.Length; i++)
        {
            var order = "/{ulong=" + i + "}";
            var keyword = keywordArray[i];
            metadata.SetQuery("/xmp/<xmpbag>dc:Subject" + order, keyword);
        }
        // Write in the IPTC section
        metadata.SetQuery("/app13/irb/8bimiptc/iptc/{str=Keywords}", keywordArray);
        // Create a bitmap encoder
        var encoder = CreateBitmapEncoder(imageFormat);
        // Create new frame with the updated metadata
        // Keep everything the same except the updated metadata
        encoder.Frames.Add(BitmapFrame.Create(
            bitmapFrame, bitmapFrame.Thumbnail, metadata, bitmapFrame.ColorContexts));
        // Attemp to save the update image
        using (Stream outputFile = File.Open(path + tempSufix, FileMode.Create, FileAccess.ReadWrite))
        {
            encoder.Save(outputFile);
        }
    }
}