Join us and panelists from Shopify, Figma, Loom, and Fnatic for the next Sanity.io Open House. Dec 8th.

Image Metadata

This article takes a closer look at the types of metadata available for images, and the values they might return.

The metadata option for image fields warrants a closer look. It takes an array of strings describing which types of metadata Sanity should attempt to extract or generate from uploaded images and save alongside the asset. An example of an image field with every metadata option specified looks as follows:


  {
      name: 'metaImage',
      title: 'Image with metadata',
      type: 'image',
      options: {
        metadata: [
          'dimensions', // Always included
          'hasAlpha',   // Always included
          'isOpaque',   // Always included
          'blurhash',   // Default: included
          'lqip',       // Default: included
          'palette',    // Default: included
          'exif',       // Default: not included
          'location',   // Default: not included
        ],
      },
    },

As seen above, the metadata fields fall into one of three different "default behaviors" – Always included, included by default, and not included by default. We'll look at each default setting and the metadata fields that adhere to it.

Dimensions, Alpha Channel, and Opaqueness

Always included

These values are always available whether or not you ask for them. As such there's really no need to specify these values in your schema, but we include them here for completeness' sake.

hasAlpha and isOpaque

hasAlpha will return true if the image has an alpha channel, even if unused, while isOpaque returns true if the image is fully opaque, i.e. has no transparency.

dimensions

The dimensions object contains the numeric values: aspectRatio, height, and width, which together describe the physical features of the image. A photo taken in portrait mode might yield the following payload:

{
  "dimensions" : {
    "_type": "sanity.imageDimensions",
    "aspectRatio": 0.75,
    "height": 4032,
    "width": 3024
  }
}

Placeholders and Colors

Included by default

These values are available by default. If you don't ask for any metadata at all, you still get these without asking! Beware though: If you do specify any other kind of metadata and leave these out, they will be missing!

lqip and blurhash

Sanity will generate low-fidelity representations of your images automatically. These are useful for creating placeholders for loading images in your frontend. These downsampled previews come in two different flavors:

LQIP (Low-Quality Image Preview) is a 20px wide version of your image (height according to aspect ratio) in the form of a base64-encoded string and can be used in your frontend without further ado, as shown below. A typical value for lqip might look like this:


"lqip": "data:image/png;base64,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"

And can be put into use like this:


		<!-- 
			The LQIP value is actual image data
			encoded into a base64-string which can be 
			used directly as the src property of an img tag!
			Remember to set the height and width 
			properties, though, or it'll be very small
		-->
		<img
      height="100"
      width="100"
      src="data:image/png;base64,iVBORw0KGgo[...50 lines of this stuff omitted for brevity...]Jggg=="
    />

Blurhash is a more advanced method of creating a lightweight image preview that can give a superior result and comes in a somewhat less unwieldy format; The trade-off being that you'll need to decode the value using a helper library before use. A blurhash value might look something like this:


"blurHash" : "d79Z$I-o4:IoxaofR*WC00Io?GxtM{Rkt7s:~VxaNGRk"

Example of use in a JavaScript project:

import { decode } from "blurhash";

const pixels = decode("LEHV6nWB2yk8pyo0adR*.7kCMdnj", 32, 32);

const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const imageData = ctx.createImageData(width, height);
imageData.data.set(pixels);
ctx.putImageData(imageData, 0, 0);
document.body.append(canvas);

palette

Sanity will generate a color palette by analyzing your image. Along with the dominant swatches, suggestions for colors that contrast nicely with them is returned, as well as a numeral indication of how prominently each color is represented in the image. A palette object example:

{
  "_type": "sanity.imagePalette",
  "darkMuted": {
    "_type": "sanity.imagePaletteSwatch",
    "background": "#653a2d",
    "foreground": "#fff",
    "population": 3.8,
    "title": "#fff"
  },
  "darkVibrant": {
    "_type": "sanity.imagePaletteSwatch",
    "background": "#c4850b",
    "foreground": "#fff",
    "population": 0.08,
    "title": "#fff"
  },
  "dominant": {
    "_type": "sanity.imagePaletteSwatch",
    "background": "#d5c3ba",
    "foreground": "#000",
    "population": 7.17,
    "title": "#fff"
  },
  "lightMuted": {
		// [...] truncated for brevity
  },
  "lightVibrant": {
		// [...]
  },
  "muted": {
		// [...]
  },
  "vibrant": {
		// [...]
  }
}

Camera and Location

Unavailable by default

These values are not included in your image metadata unless specifically asked for as they might contain private information.

exif

Short for Exchangeable Image File format, this field contains information about the image file itself and the conditions under which it was produced – typically camera settings. Exactly what data is contained here depends on the origins of the file. Below is an example readout of the Exif object for a photo taken with an iPhone camera:

{
  "_type": "sanity.imageExifMetadata",
  "ApertureValue": 1.6959938128383605,
  "BrightnessValue": 1.7619172145845785,
  "DateTimeDigitized": "2020-03-19T12:25:17.000Z",
  "DateTimeOriginal": "2020-03-19T12:25:17.000Z",
  "ExposureBiasValue": 0,
  "ExposureMode": 0,
  "ExposureProgram": 2,
  "ExposureTime": 0.020833333333333332,
  "FNumber": 1.8,
  "Flash": 16,
  "FocalLength": 4.25,
  "FocalLengthIn35mmFormat": 26,
  "ISO": 250,
  "LensMake": "Apple",
  "LensModel": "iPhone 11 Pro back triple camera 4.25mm f/1.8",
  "LensSpecification": [
    1.5399999618512084,
    6,
    1.8,
    2.4
  ],
  "MeteringMode": 5,
  "PixelXDimension": 4032,
  "PixelYDimension": 3024,
  "SceneCaptureType": 0,
  "SensingMethod": 2,
  "ShutterSpeedValue": 5.586024712398807,
  "SubSecTimeDigitized": "900",
  "SubSecTimeOriginal": "900",
  "SubjectArea": [
    2323,
    710,
    1410,
    1412
  ],
  "WhiteBalance": 0
}

location

This field, as you might expect, returns geographical data, usually representing the coordinates from which the photo was taken. It conforms to the specification of the geopoint schema type, and might look like this:

{
  "_type": "geopoint",
  "alt": 168.32554596241746,
  "lat": 59.948811111111105,
  "lng": 10.867780555555557
}

In conclusion

Image assets in your Sanity Content Lake may include a range of useful metadata.

  • Always included: Essential facts about your image. I.e. height, width, aspect ratio, and information about transparency.
  • Included by default: Useful info generated from the image on upload. I.e. minified placeholders and palette values.
  • Not included unless specified: Potentially vulnerable info about the location and circumstances under which the image originates.

Was this article helpful?