Docs / Transformers / Image Metadata

# Image Metadata

Extract EXIF metadata — capture date, camera, lens, exposure, GPS — from an image and merge it onto the payload. Runs 100% on-device — no network, no AI provider required.

Every photo a camera takes carries hidden EXIF metadata: when it was shot, on what camera and lens, at what settings, and (when location was on) where. Image Metadata reads that block and exposes it as payload variables, so downstream nodes can reference values like `{{exif.dateTakenCompact}}` or `{{exif.cameraModel}}`. It pairs naturally with the Photo Added trigger and the Rename File node's operation stack — the classic "rename every photo by its capture date" workflow is three nodes.

## Ports

Inlet
Input (image)
Outlet
Output (any)

## Configuration

Parameter | Type | Default | Description
--- | --- | --- | ---
`imagePath` | variable picker | `{{filePath}}` | The image to read. Defaults to `{{filePath}}` from the upstream node.

## Output Payload

These keys are merged onto the incoming payload — upstream keys such as `filePath` are preserved, so a later node can still act on the photo. EXIF values land under a nested `exif` object that you reference with dot paths: `{{exif.dateTaken}}`, `{{exif.gpsLatitude}}`, and so on. Keys the image doesn't carry are omitted — a missing `{{exif.*}}` token renders as an empty string in templates.

Variable | Type | Description
--- | --- | ---
success | Boolean | `false` when the image was missing, unreadable, or not an image (the node never aborts the workflow — branch on this with a Compare node).
hasExif | Boolean | `true` when the image carried real EXIF beyond pixel dimensions — a screenshot or web download is typically `false`.
error | String | On failure only: what went wrong (e.g. `not_an_image`).
exif.dateTaken | String | Capture date as ISO-8601 (e.g. `2023-06-15T14:30:22`).
exif.dateTakenCompact | String | Capture date as a filename-safe stamp (e.g. `20230615-143022`) — the one to use in rename templates.
exif.cameraMake | String | Camera manufacturer (e.g. Apple).
exif.cameraModel | String | Camera model (e.g. iPhone 15 Pro).
exif.lensModel | String | Lens description, when the camera recorded one.
exif.focalLength | Number | Focal length in millimeters.
exif.aperture | Number | Aperture f-number (e.g. 2.8).
exif.iso | Number | ISO sensitivity used for the shot.
exif.shutterSpeed | String | Photographer-style exposure time (e.g. `1/250`).
exif.pixelWidth / exif.pixelHeight | Number | Image dimensions in pixels.
exif.orientation | Number | EXIF orientation flag (1–8).
exif.gpsLatitude / exif.gpsLongitude | Number | Location in signed decimal degrees (south / west are negative).

For convenience, the four most-templated values — `dateTaken`, `dateTakenCompact`, `cameraModel`, and `lensModel` — are also copied to the top level of the payload, so `{{dateTakenCompact}}` works without the dot path.

## Example: rename photos by capture date

The classic photo-rename workflow: Photo Added fires with the new photo's `filePath`, Image Metadata reads its EXIF, and Rename File stamps the capture date onto the name. In Rename File, leave the Base Name template empty (keeps the original name) and add an Insert Text operation with text `{{exif.dateTakenCompact}}-` at Start — `IMG_4302.JPG` becomes `20230615-143022-IMG_4302.JPG`. See Rename File for the full operation stack.

← Extract Text (OCR) Extract Text (PDF) →