This documentation is for the old version. Go to the latest Graphics Mill docs

Loading or Saving XMP Metadata

XMP stands for eXtensible Metadata Platform. This is a specific type of XML that was first introduced by Adobe Systems. XMP defines a metadata model that can be used with any defined set of metadata items. It also defines some schemas for basic properties for recording the history of image modifications. XMP records metadata in a Resource Description Framework syntax (RDF) that is expressed in XML.

XMP can be used in the following graphics formats supported by Graphics Mill for .NET: JPEG and TIFF.

Reading XMP Metadata

Overview

To read XMP metadata in Graphics Mill for .NET, you will need to read the Xmp property value of the opened reader. Currently, only few readers provide this property:

The Xmp property returns a string containing an XML code. This XML code is the XMP metadata. As you probably do not want to parse this XML on your own, pass it as a parameter to the constructor of the XmpData class. This class represents a tree-like structure of the metadata. This structure is a hierarchical collection of nodes.

The nodes can be of several different types:

Each node is a descendant of the XmpNode class.

The nodes contain tags. The tags belong to different schemas. A schema is a pre-defined set of some properties (tags); schemas are identified by their namespaces which follow the usage of XML namespaces. The use of namespaces helps to avoid conflicts between properties with the same name but different meanings. Namespaces in Graphics Mill for .NET are represented by the XmpNamespace class. Graphics Mill for .NET contains several namespaces that are defined in the XMP specification, but you may add your own ones.

Examples

Now, when you know how XMP data is organized, you can read it from a file. The following example demonstrates how to iterate through all properties in the XmpData collection using the Values property.

Visual Basic
Dim reader As New Aurigma.GraphicsMill.Codecs.JpegReader("C:\IMG_0001.jpg")

'Check if XMP data are present in the file
If reader.Xmp <> Nothing Then
    'Get an XML code from the reader
    Dim xmp As New Aurigma.GraphicsMill.Codecs.XmpData(reader.Xmp)

    'Go through all simple value nodes and print them along with their tags
    Dim node As Aurigma.GraphicsMill.Codecs.XmpNode
    For Each node In xmp.Values
        If node.NodeType = Aurigma.GraphicsMill.Codecs.XmpNodeType.SimpleProperty Then
            Console.WriteLine("{0}: {1}", node.Name, node.ToString())
        End If
    Next node
End If
C#
Aurigma.GraphicsMill.Codecs.JpegReader reader = new
    Aurigma.GraphicsMill.Codecs.JpegReader(@"C:\IMG_0001.jpg");

//Check if XMP data are present in the file
if (reader.Xmp != null)
{
    //Get an XML code from the reader
    Aurigma.GraphicsMill.Codecs.XmpData xmp = new
        Aurigma.GraphicsMill.Codecs.XmpData(reader.Xmp);
    //Go through all simple value nodes and print them along with their tags
    foreach (Aurigma.GraphicsMill.Codecs.XmpNode node in xmp.Values)
    {
        if (node.NodeType == Aurigma.GraphicsMill.Codecs.XmpNodeType.SimpleProperty)
            Console.WriteLine("{0}: {1}", node.Name, node.ToString());
    }
}

However, you may not only iterate through all XMP properties but also get only specific ones that you need. The following example shows how to do it.

Visual Basic
Dim reader As New Aurigma.GraphicsMill.Codecs.JpegReader("C:\IMG_0001.jpg")

'Check if XMP data are present in the file
If reader.Xmp <> Nothing Then
    'Get an XML code from the reader
    Dim xmp As New Aurigma.GraphicsMill.Codecs.XmpData(reader.Xmp)

    'Print the value of the xmp:CreatorTool tag if it exists
    If xmp.Contains(Aurigma.GraphicsMill.Codecs.XmpTagNames.XmpCreatorTool) Then
        Console.WriteLine("This image was created using {0}", _
         xmp.Item(Aurigma.GraphicsMill.Codecs.XmpTagNames.XmpCreatorTool))
    End If
End If
C#
Aurigma.GraphicsMill.Codecs.JpegReader reader = new
    Aurigma.GraphicsMill.Codecs.JpegReader(@"C:\IMG_0001.jpg");

//Check if XMP data are present in the file
if (reader.Xmp != null)
{
    //Get an XML code from the reader
    Aurigma.GraphicsMill.Codecs.XmpData xmp = new
        Aurigma.GraphicsMill.Codecs.XmpData(reader.Xmp);

    //Print the value of the xmp:CreatorTool tag if it exists
    if (xmp.Contains(Aurigma.GraphicsMill.Codecs.XmpTagNames.XmpCreatorTool))
    {
        Console.WriteLine("This image was created using {0}",
            xmp[Aurigma.GraphicsMill.Codecs.XmpTagNames.XmpCreatorTool]);
    }
}

Writing XMP Metadata

Overview

To write XMP metadata in Graphics Mill for .NET, you will need to modify the Xmp property value of the opened writer. Currently, only few writers provide this property:

The Xmp property of these writers has the same meaning as the Xmp property of the corresponding readers and is a string containing an XML code. You can construct this string yourself, but this approach is error-prone. A better way is to do it using the XmpData class.

The XmpData class provides the AddNode(XmpNode) method which adds any descendant of the XmpNode class to the current tree. You can also remove unwanted nodes using the Remove(Object) method. After you are done with the tree, call the Save() method which returns a string suitable for setting it as a value of the Xmp property.

Example

The following example demonstrates how to add an XMP property and save it with the file.

Visual Basic
Dim reader As New Aurigma.GraphicsMill.Codecs.JpegReader("C:\IMG_0001.jpg")
Dim xmp As Aurigma.GraphicsMill.Codecs.XmpData

'Check if XMP data are present in the file and...
If reader.Xmp <> Nothing Then
    '...get an XML code from the reader
    xmp = New Aurigma.GraphicsMill.Codecs.XmpData(reader.Xmp)
Else
    '...or create an empty structure
    xmp = New Aurigma.GraphicsMill.Codecs.XmpData
End If

'Check if the dc:Creator tag exists and remove it in this case
If xmp.Contains(Aurigma.GraphicsMill.Codecs.XmpTagNames.DCCreator) Then
    xmp.Remove(Aurigma.GraphicsMill.Codecs.XmpTagNames.DCCreator)
    'Otherwise, add it
Else
    Dim node As New Aurigma.GraphicsMill.Codecs.XmpValueNode( _
     Aurigma.GraphicsMill.Codecs.XmpNodeType.SimpleProperty, _
     "John Doe", Aurigma.GraphicsMill.Codecs.XmpTagNames.DCCreator)
    xmp.AddNode(node)
End If

'Copy the bitmap of the original file
Dim bitmap As New Aurigma.GraphicsMill.Bitmap
Dim frame As Aurigma.GraphicsMill.Codecs.IFrame = reader.LoadFrame(0)
frame.GetBitmap(bitmap)
frame.Dispose()

Dim writer As New Aurigma.GraphicsMill.Codecs.JpegWriter("C:\IMG_0002.jpg")

'Save modified metadata with the file
writer.Xmp = xmp.Save()
frame = New Aurigma.GraphicsMill.Codecs.JpegFrame(bitmap, 70, False)
writer.AddFrame(frame)
C#
Aurigma.GraphicsMill.Codecs.JpegReader reader = new
    Aurigma.GraphicsMill.Codecs.JpegReader(@"C:\IMG_0001.jpg");
Aurigma.GraphicsMill.Codecs.XmpData xmp = null;

//Check if XMP data are present in the file and...
if (reader.Xmp != null)
{
    //...get an XML code from the reader
    xmp = new Aurigma.GraphicsMill.Codecs.XmpData(reader.Xmp);
}
else
{
    //...or create an empty structure
    xmp = new Aurigma.GraphicsMill.Codecs.XmpData();
}

//Check if the dc:Creator tag exists and remove it in this case
if (xmp.Contains(Aurigma.GraphicsMill.Codecs.XmpTagNames.DCCreator))
{
    xmp.Remove(Aurigma.GraphicsMill.Codecs.XmpTagNames.DCCreator);
}
//Otherwise, add it
else
{
    Aurigma.GraphicsMill.Codecs.XmpValueNode node = new
        Aurigma.GraphicsMill.Codecs.XmpValueNode(
        Aurigma.GraphicsMill.Codecs.XmpNodeType.SimpleProperty, "John Doe",
        Aurigma.GraphicsMill.Codecs.XmpTagNames.DCCreator);
    xmp.AddNode(node);
}

//Copy the bitmap of the original file
Aurigma.GraphicsMill.Bitmap bitmap = new Aurigma.GraphicsMill.Bitmap();
Aurigma.GraphicsMill.Codecs.IFrame frame = reader.LoadFrame(0);
frame.GetBitmap(bitmap);
frame.Dispose();

Aurigma.GraphicsMill.Codecs.JpegWriter writer = new
    Aurigma.GraphicsMill.Codecs.JpegWriter(@"C:\IMG_0002.jpg");

//Save modified metadata with the file
writer.Xmp = xmp.Save();
frame = new Aurigma.GraphicsMill.Codecs.JpegFrame(bitmap, 70, false);
writer.AddFrame(frame);

See Also

Reference

Manual