Strip or edit metadata
editA 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.Orientationto 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
nullremoves the GPS position with the rest. - Text entries are the comments and the text chunks of the file, such as the
Commentof 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:
| Policy | Writes | When the format cannot store some metadata |
|---|---|---|
| Strict (default) | Everything the image has | Throws an UnsupportedImageFeatureException before writing anything |
| DiscardUnsupported | What the format can store | Drops the rest |
| Strip | Nothing optional | Nothing 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 });
}| Property | Contains |
|---|---|
| Orientation | How viewers must turn the pixels (ExifOrientation); TopLeft means as stored |
| Resolution | The pixel density, in dots per inch (ImageResolution), used for printing |
| TextEntries | Key and value pairs (ImageTextEntry): a title, a comment, a copyright |
| IccProfile | The color profile that labels the pixels |
| ExifProfile, XmpProfile | The 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).