ExifTool Rust Wrapper
Rust wrapper for Phil Harvey's ExifTool command-line application.
This crate interacts with a persistent exiftool
process using the -stay_open
argument, significantly reducing
overhead compared to spawning a new process for each command.
Note: This crate assumes that the exiftool
command-line executable is available already, via PATH or by passing an
executable.
Features
- 🚀 Fast: Uses a long-running
exiftool
process (-stay_open
) for minimal overhead per command. - 🦀 Rust-friendly: Simple typed API with clear error handling (
ExifToolError
), andserde
support for deserialization. - ✅ Robust: Tested cross-platform, CI across Windows, Linux, and macOS.
- 🛠️ Flexible:
- Read/Write string and binary tags.
- Retrieve metadata as structured JSON (
serde_json::Value
). - Deserialize JSON output directly into your own Rust structs or use the provided
ExifData
. - Execute lower-level commands when needed.
Prerequisites
You must have Phil Harvey's ExifTool command-line utility installed and accessible in your system's PATH.
- Official Website & Installation: https://exiftool.org/
- macOS (Homebrew):
brew install exiftool
- Debian/Ubuntu:
sudo apt install libimage-exiftool-perl
- Windows: Download the Windows Executable from the official website and ensure its location is in your PATH environment variable.
Verify your installation by typing exiftool -ver
in your terminal.
Usage Examples
Read a Single Tag
use ;
use Path;
Read All Metadata (as JSON Value
)
use ;
use Path;
Read and Deserialize All Metadata into a Struct.
There's a provided struct (ExifData
) for dealing with common fields, if you want that type safety. -g2
has to be
used to use this struct.
use ;
use Path;
Read Metadata for Multiple Files (Batch)
use ;
use Path;
Read Binary Data (e.g., Thumbnail)
use ;
use Path;
use fs;
Write a Tag
Warning: ExifTool creates a backup file named {filename}_original
when writing.
use ;
use ;
use fs;
Write Binary Data
Uses a temporary file internally. Also creates {filename}_original
as backup.
use exiftool::{ExifTool, ExifToolError};
use std::path::{Path, PathBuf};
use std::fs;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut exiftool = ExifTool::new()?;
let source_path = Path::new("data/image.jpg");
// Create some dummy binary data (e.g., a tiny valid JPEG)
let dummy_thumb = b"\xFF\xD8\xFF\xE0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xFF\xDB\x00C\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xFF\xC0\x00\x11\x08\x00\x01\x00\x01\x03\x01\x22\x00\x02\x11\x01\x03\x11\x01\xFF\xC4\x00\x15\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xDA\x00\x0C\x03\x01\x00\x02\x11\x03\x11\x00\x3F\x00\xA8\xFF\xD9";
println!("Writing binary ThumbnailImage to: {}", source_path.display());
exiftool.write_tag_binary(&source_path, "ThumbnailImage", &dummy_thumb[..], &[])?;
println!("Binary write successful.");
// Verify (Optional)
let read_thumb = exiftool.read_tag_binary(&source_path, "ThumbnailImage")?;
assert_eq!(read_thumb, dummy_thumb);
println!("Binary verification successful!");
Ok(())
}
Execute Lower-Level Commands
For commands not covered by helpers, use execute_lines
(string lines), json_execute
(json value), or execute_raw
(
bytes).
use ;
Provided Struct (ExifData
)
This crate provides exiftool::ExifData
. This struct maps many common fields
output by exiftool -g2 -json
. It's useful for accessing typed data for standard image and video metadata.
- See the structs/g2.rs file for details on the available fields.
- Remember to pass
"-g2"
when callingread_metadata
.
Error Handling
All potentially failing operations return Result<_, ExifToolError>
. The
ExifToolError
enum covers
various issues, including:
- IO errors communicating with the process.
- ExifTool executable not found.
- Errors reported by the ExifTool process (e.g., file not found, invalid arguments).
- JSON parsing/deserialization errors.
- Tag not found errors.
- Process termination issues.
Performance
By keeping a single exiftool process running (-stay_open True -@ -), this wrapper avoids the significant startup cost associated with launching exiftool for every command, making it suitable for batch processing or applications requiring frequent metadata access.