Preserving Metadata while Processing Images

When you process JPEG or TIFF images, you may wonder what happens to EXIF and IPTC metadata. It is especially important when you use some specific software to handle the resulting images, for example printing them at a photo lab or categorizing them based on metadata.

Fortunately, Graphics Mill provides an elegant way to preserve metadata. The idea is quite simple: use an image reader to get not only the bitmap but also metadata from a source image, and when the image is processed put the modified bitmap and the metadata in a resulting file via an image writer.

The code snippet below demonstrates how to implement this approach. The code does the following:

  1. Loads an image and associated EXIF, IPTC, XMP fields, and Adobe® image resource blocks.
  2. Resizes the image.
  3. Updates metadata.
  4. Saves the new image and metadata to a file.
C#
using (var jpegReader = new Aurigma.GraphicsMill.Codecs.JpegReader(@"Images/in.jpg"))
using (var resizer = new Aurigma.GraphicsMill.Transforms.Resize(jpegReader.Width / 2, 0))
using (var jpegWriter = new Aurigma.GraphicsMill.Codecs.JpegWriter(@"Images/out.jpg"))
{
    //Read EXIF
    var exif = jpegReader.Exif;
    //Check if loaded image contains EXIF metadata
    if (exif == null)
    {
        exif = new Aurigma.GraphicsMill.Codecs.ExifDictionary();
    }
    exif[Aurigma.GraphicsMill.Codecs.ExifDictionary.Software] = "Aurigma Graphics Mill";

    //Read IPTC
    var iptc = jpegReader.Iptc;
    //Check if loaded image contains IPTC metadata
    if (iptc == null)
    {
        iptc = new Aurigma.GraphicsMill.Codecs.IptcDictionary();
    }
    iptc[Aurigma.GraphicsMill.Codecs.IptcDictionary.Keyword] = "mountain";

    //Read Adobe resource blocks
    var adobeResources = jpegReader.AdobeResources;
    //Check if loaded image contains Adobe image resource blocks
    if (adobeResources == null)
    {
        adobeResources = new Aurigma.GraphicsMill.Codecs.AdobeResourceDictionary();
    }
    //Create new adobe image resource block containing copyright metadata
    var arBlock = new Aurigma.GraphicsMill.Codecs.AdobeResourceBlock("Copyright", new byte[] { 1 });
    //Set this block to the item with 0x040A ID (copyright flag)
    adobeResources[0x040A] = arBlock;

    //Read XMP
    var xmp = new Aurigma.GraphicsMill.Codecs.XmpData();
    //Check if loaded image contains XMP metadata
    if (jpegReader.Xmp != null)
    {
        xmp.Load(jpegReader.Xmp);
    }
    //Create a node containing dc:creator metadata
    var node = new Aurigma.GraphicsMill.Codecs.XmpValueNode(
            Aurigma.GraphicsMill.Codecs.XmpNodeType.SimpleProperty,
            "John Doe",
            Aurigma.GraphicsMill.Codecs.XmpTagNames.DCCreator);
    xmp.AddNode(node);

    //Write metadata
    jpegWriter.Exif = exif;
    jpegWriter.Iptc = iptc;
    jpegWriter.AdobeResources = adobeResources;
    jpegWriter.Xmp = xmp.Save();

    Aurigma.GraphicsMill.Pipeline.Run(jpegReader + resizer + jpegWriter);
}