Skip to content

exif

stable

Read and inspect EXIF metadata embedded in JPEG and TIFF image files. Extract camera info, GPS coordinates, orientation, timestamps, and arbitrary tag values.

use plugin exif::{read_file, get_tag, has_gps, …}
10 functions Image
/ filter jk navigate Esc clear
Functions (10)
  1. read_file Read all EXIF tags from an image file
  2. get_tag Find a tag value by name in a tag table
  3. has_gps Check if a tag table contains GPS data
  4. image_dimensions Read pixel width and height from file
  5. camera_info Extract make and model from a tag table
  6. list_tags List all tag names from a tag table
  7. tag_count Count the number of tags in a table
  8. orientation Get the Orientation tag value
  9. gps_coords Extract latitude and longitude strings
  10. date_time Get the DateTimeOriginal or DateTime value

Overview

exif reads the EXIF metadata block embedded in JPEG and TIFF photos and exposes it to Zolo as plain tables of {tag, value_str} entries. The whole API is stateless: read_file (or image_dimensions) opens a file once and hands back an ordinary table, and every other function is a pure query over that table — there are no handles to close and no mutable state to track. Pixel dimensions, camera make/model, GPS coordinates, orientation, and capture timestamps are all just tags in the same block, so the convenience helpers simply locate the right entries for you.

The mental model is a two-step pipeline: call read_file(path) once to get the entries table, then pass that table into the helpers (get_tag, camera_info, gps_coords, orientation, date_time, list_tags, tag_count, has_gps). The lone exception is image_dimensions, which takes a file path directly rather than an entries table. Use this plugin whenever you need to inspect what a camera recorded about a photo without decoding the image pixels themselves.

Common patterns

Read a photo once, then summarize the camera and capture details:

use plugin exif::{read_file, camera_info, date_time, orientation}

let tags = read_file("photo.jpg")
let cam  = camera_info(tags)
print("camera: {cam["make"]} {cam["model"]}")
print("taken:  {date_time(tags)}")
print("orient: {orientation(tags)}")

Guard GPS access with has_gps before pulling coordinates:

use plugin exif::{read_file, has_gps, gps_coords}

let tags = read_file("photo.jpg")
if has_gps(tags) {
  let coords = gps_coords(tags)
  print("{coords["latitude"]} {coords["latitude_ref"]}")
  print("{coords["longitude"]} {coords["longitude_ref"]}")
} else {
  print("no location embedded")
}

Combine the file-path and entries-table APIs into one report:

use plugin exif::{read_file, image_dimensions, tag_count, get_tag}

let path = "photo.jpg"
let tags = read_file(path)
let dims = image_dimensions(path)
print("{dims["width"]}x{dims["height"]} with {tag_count(tags)} tags")
print("exposure: {get_tag(tags, "ExposureTime")}")

Read all EXIF tags from an image file

Opens an image file and reads all primary EXIF tags. Returns a table of {tag, value_str} entries. This table is the input for most other functions in this plugin.

use plugin exif::{read_file, list_tags}

let tags = read_file("photo.jpg")
let names = list_tags(tags)
print(names)

Because the result is an ordinary table, you can feed it straight into the other helpers without re-reading the file:

use plugin exif::{read_file, tag_count, camera_info}

let tags = read_file("photo.jpg")
print("read {tag_count(tags)} tags")
print(camera_info(tags)["model"])

Find a tag value by name in a tag table

Searches the tag table returned by read_file for an entry whose tag field matches tag_name. Returns the string value, or nil if not found.

use plugin exif::{read_file, get_tag}

let tags  = read_file("photo.jpg")
let iso   = get_tag(tags, "ISOSpeedRatings")
let focal = get_tag(tags, "FocalLength")
print("ISO: {iso}, focal: {focal}")

Since a missing tag comes back as nil, you can branch on the result to handle photos that lack a particular field:

use plugin exif::{read_file, get_tag}

let tags = read_file("photo.jpg")
let lens = get_tag(tags, "LensModel")
if lens != nil {
  print("shot with {lens}")
} else {
  print("lens not recorded")
}

Check if a tag table contains GPS data

Returns true if the tag table contains any GPS-related tags (GPSLatitude, GPSLongitude, etc.).

use plugin exif::{read_file, has_gps}

let tags = read_file("photo.jpg")
if has_gps(tags) {
  print("image has location data")
}

Read pixel width and height from file

Reads PixelXDimension and PixelYDimension directly from the file. Returns {width, height} as integers (0 if the tags are absent).

use plugin exif::{image_dimensions}

let dims = image_dimensions("photo.jpg")
print("size: {dims["width"]}x{dims["height"]}")

The width and height are integers, so you can compute derived values like the aspect ratio or megapixel count directly:

use plugin exif::{image_dimensions}

let dims = image_dimensions("photo.jpg")
let mp   = (dims["width"] * dims["height"]) / 1000000
print("{mp} megapixels")

Extract make and model from a tag table

Extracts the Make and Model tag values from a tag table. Returns {make, model} as strings (empty if not present).

use plugin exif::{read_file, camera_info}

let tags = read_file("photo.jpg")
let cam  = camera_info(tags)
print("{cam["make"]} {cam["model"]}")

List all tag names from a tag table

Returns a flat table of all tag name strings present in the tag table. Useful for discovery and debugging.

use plugin exif::{read_file, list_tags}

let tags  = read_file("photo.jpg")
let names = list_tags(tags)
print("found {tag_count(tags)} tags")

Count the number of tags in a table

Returns the number of EXIF tags in the table.

use plugin exif::{read_file, tag_count}

let tags = read_file("photo.jpg")
print(tag_count(tags))

Get the Orientation tag value

Returns the value of the Orientation tag (e.g., "top-left", "right-top"). Returns nil if the tag is absent.

use plugin exif::{read_file, orientation}

let tags = read_file("photo.jpg")
let o    = orientation(tags)
if o != nil {
  print("orientation: {o}")
}

Extract latitude and longitude strings

Extracts GPSLatitude, GPSLongitude, GPSLatitudeRef, and GPSLongitudeRef tag values. Returns a table with those four keys, or nil if GPS data is absent.

use plugin exif::{read_file, gps_coords}

let tags   = read_file("photo.jpg")
let coords = gps_coords(tags)
if coords != nil {
  print("{coords["latitude"]} {coords["latitude_ref"]}")
  print("{coords["longitude"]} {coords["longitude_ref"]}")
}

Pair it with has_gps so you only build the coordinate string when location data is actually present:

use plugin exif::{read_file, has_gps, gps_coords}

let tags = read_file("photo.jpg")
if has_gps(tags) {
  let c = gps_coords(tags)
  print("located at {c["latitude"]}{c["latitude_ref"]}, {c["longitude"]}{c["longitude_ref"]}")
}

Get the DateTimeOriginal or DateTime value

Returns the value of DateTimeOriginal (preferred) or DateTime, or nil if neither is present. The format is typically "YYYY:MM:DD HH:MM:SS".

use plugin exif::{read_file, date_time}

let tags = read_file("photo.jpg")
let dt   = date_time(tags)
print("taken: {dt}")
enespt-br