Metadata and orientation

edit

image.Metadata holds everything an image says about itself besides its pixels. Decoders fill it, encoders write it, and you can read and change it in between.

MemberWhat it is
OrientationThe EXIF orientation: which way is up
IccProfileThe ICC color profile that describes the samples
ExifProfile, XmpProfileThe EXIF and XMP payloads, kept byte for byte
TextEntriesText entries, such as the tEXt chunks of PNG or the comments of GIF and JPEG
ResolutionThe horizontal and vertical resolution, in dots per inch
PixelAspectRatioThe relative width and height of a pixel, for formats whose pixels are not square
Cicp, TransferFunction, ContentLightLevel, MasteringDisplayColor descriptions of AVIF, HEIC, PNG, JPEG XL and QOI images: see Color management
SourceFormatThe format the image was loaded from, for information only

Each frame also has its own metadata (frame.Metadata): its duration in an animation, and the hotspot of a cursor. Decoded metadata is bounded by MaxMetadataBytes (16 MiB by default), decompressed text included: see Resource limits.

Apply the EXIF orientation

A camera stores a photo as its sensor saw it, and records in its EXIF orientation how to turn it. Decoders report that orientation and never move a pixel. Call AutoOrient to make the pixels upright:

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

    // The orientation the camera recorded: the decoder reports it and leaves the pixels as they are stored
    var orientation = image.Metadata.Orientation;

    // Turns or mirrors every frame so that the pixels are upright, and sets the orientation to TopLeft: a viewer
    // that ignores the orientation then shows the same picture as one that applies it
    image.AutoOrient();

    // The orientation tag of the EXIF block is rewritten to match; the other metadata are kept
    image.Save(outputPath);
    return orientation;
}
  • AutoOrient handles the eight orientations (turns and mirrors) of every frame, and sets Orientation to TopLeft. It is all or nothing, like the other geometry changes.
  • Apply the orientation before you crop, resize or draw: the coordinates you give are those of the stored pixels.
  • On save, Orientation is authoritative: the orientation and dimension tags of the EXIF block are rewritten, and a thumbnail that a geometry change made stale is removed.
  • A format without EXIF (GIF, QOI, BMP, TGA, Netpbm) cannot store another orientation than TopLeft. Apply the orientation first: otherwise saving throws, or with MetadataHandling.DiscardUnsupported the orientation is dropped and the picture is shown as it is stored.

See Handle phone photos for a complete solution.

Edit metadata

Change the members of image.Metadata, then save:

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 });
}
  • Set a member to null to remove it: image.Metadata.ExifProfile = null removes the EXIF block.
  • A malformed EXIF, ICC or XMP payload you set is rejected when the image is saved.
  • Unknown chunks, segments and boxes of a file are skipped when it is read: they are not written back.

See Strip or edit metadata for a complete solution.

Choose what saving does with metadata

Each format stores some metadata and not others. ImageEncoder.MetadataHandling says what happens to the metadata the output format cannot store:

MetadataHandlingBehavior
Strict (the default)Throws an UnsupportedImageFeatureException: nothing is lost silently
DiscardUnsupportedWrites what the format can store and drops the rest
StripWrites no optional metadata

Animation timing is never affected by this setting. What each format stores:

FormatICC profileEXIF and orientationXMPText entries
PNGYesYesYesYes
JPEGYesYes (up to 65,527 bytes)Standard XMP (up to 65,504 bytes)Comments
WebPRGB profilesYesYesNo
GIFNoNoNoComments
TIFFYesOrientation onlyYesNo
AVIF, HEICYesYesYesNo
JPEG XLYesYesYesNo
JPEG 2000 (JP2)Gray and matrix RGB profilesYesYesNo
QOI, BMP, TGA, NetpbmNoNoNoNo

ICO files store no metadata, and HEIC does not store the orientation of an image sequence yet. The pages of the formats give the details, such as the resolution, the color descriptions and the limits of each container.

Cursor hotspots

The hotspot of a cursor is the metadata of each frame (frame.Metadata.Hotspot). CUR and ANI files always store one per image, the top-left corner when a frame has none. Every other format cannot store it: the hotspot follows MetadataHandling like other metadata, so a cursor is never saved as a plain picture without an explicit choice. See ICO and CUR and ANI.