Strip or edit metadata

edit

A photo carries more than its pixels: EXIF data (the GPS position, the date, the camera and its settings), XMP data, text comments, a color profile and an orientation. Some of it is private and should not be published; some of it changes how the photo looks and must not be lost. Image.Metadata holds all of it, and the encoder decides what is written.

Remove the private data and keep the colors

public static void RemovePrivateMetadata(string inputPath, string outputPath)
{
    using var image = Image.Load(inputPath);

    // The orientation is stored in the EXIF data: apply it to the pixels before removing EXIF
    image.AutoOrient();

    // EXIF holds the GPS position, the date and the camera; XMP can hold the same and more
    image.Metadata.ExifProfile = null;
    image.Metadata.XmpProfile = null;
    image.Metadata.TextEntries.Clear();

    // The ICC profile is kept: it describes the colors of the pixels, and holds nothing about the photographer
    image.Save(outputPath);
}
  • The orientation first. The orientation of a photo is an EXIF tag. AutoOrient turns the pixels and resets Metadata.Orientation to TopLeft, so the photo stays upright without its EXIF data.
  • EXIF and XMP are removed whole. ExifProfile and XmpProfile hold the raw bytes of the blocks: the library does not edit their tags one by one. Setting them to null removes the GPS position with the rest.
  • Text entries are the comments and the text chunks of the file, such as the Comment of a JPEG or GIF file and the text chunks of a PNG file.
  • The ICC profile is kept. It describes the colors of the pixels and nothing else: without it, a photo of a phone labeled Display P3 looks dull.

The format of the output follows the extension of its path, with the default MetadataHandling.Strict: what is left is written as it is, or Save throws when the format cannot store it.

Remove all the metadata

MetadataHandling.Strip writes no optional metadata at all: no EXIF, XMP, text, resolution, ICC profile or orientation. Since the orientation and the profile change how the pixels look, apply them to the pixels first:

public static void StripAllMetadata(string inputPath, string outputPath)
{
    using var image = Image.Load(inputPath);

    // Strip drops the orientation and the color profile too: apply them to the pixels first, so that the image
    // looks the same without them
    image.AutoOrient();
    image.ConvertColorProfile(PixelFormats.IsGrayscale(image.PixelFormat) ? IccProfile.SrgbGray : IccProfile.Srgb);

    image.Save(outputPath, new PngEncoder { MetadataHandling = MetadataHandling.Strip });
}

The three policies of ImageEncoder.MetadataHandling:

PolicyWritesWhen the format cannot store some metadata
Strict (default)Everything the image hasThrows an UnsupportedImageFeatureException before writing anything
DiscardUnsupportedWhat the format can storeDrops the rest
StripNothing optionalNothing to drop

The frame durations and the loop count of an animation are not metadata: no policy removes them. A cursor keeps its hotspot in the formats that are made for it (CUR and ANI).

Check what a file contains

Image.Identify returns the metadata of a file without decoding its pixels: info.Metadata.ExifProfile, XmpProfile, IccProfile, TextEntries and Orientation. Use ImageIdentifyMode.FullScan to also read the metadata stored after the pixels, which some formats allow. See Identifying images.

Edit the metadata

The properties of Image.Metadata can be set before saving:

public static void EditMetadata(string path)
{
    using var image = Image.Load(path);
    image.Metadata.TextEntries.Add(new ImageTextEntry("Title", "Sunset"));
    image.Metadata.Resolution = new ImageResolution(300, 300);
    image.Save(path, new PngEncoder { MetadataHandling = MetadataHandling.Strict });
}
PropertyContains
OrientationHow viewers must turn the pixels (ExifOrientation); TopLeft means as stored
ResolutionThe pixel density, in dots per inch (ImageResolution), used for printing
TextEntriesKey and value pairs (ImageTextEntry): a title, a comment, a copyright
IccProfileThe color profile that labels the pixels
ExifProfile, XmpProfileThe raw EXIF and XMP blocks
  • Orientation. Setting Orientation changes how viewers display the image without moving a pixel; the EXIF orientation tag is rewritten from it when the file is saved. AutoOrient does the opposite: it moves the pixels and resets the orientation.
  • The library keeps the EXIF data consistent. On save, the dimension tags of the EXIF block are updated to the size of the image, and an EXIF thumbnail that a crop, a resize or a color conversion made stale is removed, so it can no longer show the uncropped photo.
  • Each format stores different metadata. JPEG, PNG, WebP, AVIF and HEIC store EXIF, XMP and ICC profiles; GIF stores comments only; QOI, TGA and Netpbm store none. The full table is in Metadata and orientation.
  • Saving re-encodes the pixels. The library writes a file from the image, so editing the metadata of a JPEG file and saving it as JPEG compresses its pixels again.
  • Colors are never converted by a label change. Setting IccProfile relabels the pixels without changing them; to convert the colors to another profile, use ConvertColorProfile (see Color management).