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
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.