How do I extract the metadata from an image?
Read a photo's EXIF, IPTC and XMP metadata on this page: the date taken, GPS location, camera, lens and exposure. The file is read in your browser and never uploaded. The page also covers what no header holds, such as the objects and text in the picture, and how to pull both from a whole library through an API.
The short answer
A photo carries two kinds of metadata. The first is written by the camera or phone: EXIF fields such as the date taken, GPS coordinates, camera model, lens, exposure and orientation, plus IPTC and XMP fields that editing tools add. The reader on this page shows those fields for a JPEG, PNG or TIFF without uploading it, and so do the macOS Preview inspector, the Windows file Properties dialog and the exiftool command line. The second kind describes what the picture shows, such as the objects, scene, text and dominant colors, and no file header contains it; a vision model has to look at the pixels. This page covers both, for one photo or a library of millions.
Read a photo's metadata here
Runs in your browser. The file stays on your device and nothing is uploaded.
Drop a JPEG, PNG or TIFF here, or choose one from your device.
Loading the reader.
How It Works
Drop a JPEG, PNG or TIFF onto the reader at the top of this page, or choose one. The file stays on your device.
The open-source exifr library, running in your browser, parses the EXIF, GPS, IPTC and XMP blocks straight from the file's bytes.
The date taken, camera, lens, exposure and location show first. Every other field follows, grouped by the block it came from.
Download the full result as JSON.
For a whole library, the API code below runs an extractor over every image in a bucket and stores the output as documents you can search.
Which image metadata approach should I use?
| Approach | Best for | Tradeoff | Use when |
|---|---|---|---|
| Embedded metadata parser | Camera data, GPS, copyright fields, timestamps, and rights metadata that already live in the file | Fast and deterministic, but it cannot describe visual content that was never tagged | Use first on every ingest so EXIF, IPTC, and XMP are preserved before any AI enrichment. |
| Vision API enrichment | Objects, labels, landmarks, OCR, dominant colors, and content-safety fields | Generates useful descriptive metadata, but each provider returns a different schema | Use when the library needs searchable visual attributes and you can normalize provider output. |
| DAM auto-tagging | Creative teams that need a review UI, permissions, portals, and approval workflows | Operationally easy for marketers, but weaker when developers need custom retrieval behavior | Use when the metadata pipeline is primarily a creative workflow rather than an API product. |
| Mixpeek managed indexing | Object-storage libraries that need technical metadata, semantic metadata, and retrieval in one index | Requires modeling the library as a namespace and collection instead of one-off file conversion | Use when extracted metadata has to be searchable immediately across images, video, audio, and documents. |
Code Examples
import os, requests
API = "https://api.mixpeek.com"
H = {"Authorization": f"Bearer {os.environ['MIXPEEK_API_KEY']}",
"X-Namespace": os.environ["NAMESPACE_ID"]}
# 1. a bucket, with a schema that declares the field you will send
bucket = requests.post(f"{API}/v1/buckets", headers=H, json={
"bucket_name": "image-inputs",
"bucket_schema": {"properties": {"image": {"type": "image"}}},
}).json()
# 2. land the file as an object. the URL goes in data, on the blob
requests.post(f"{API}/v1/buckets/{bucket['bucket_id']}/objects", headers=H, json={
"key_prefix": "run-1",
"blobs": [{"property": "image", "type": "image",
"data": "https://example.com/photo.jpg"}],
})
# 3. a collection over that bucket, running the extractor
collection = requests.post(f"{API}/v1/collections", headers=H, json={
"collection_name": "image-to-metadata",
"source": {"type": "bucket", "bucket_ids": [bucket["bucket_id"]]},
"feature_extractor": {"feature_extractor_name": "image_extractor", "version": "v1"},
}).json()
# 4. run extraction over the bucket
requests.post(f"{API}/v1/buckets/{bucket['bucket_id']}/batches", headers=H, json={
"collection_ids": [collection["collection_id"]],
"auto_submit": True,
})
# 5. read the output
docs = requests.get(
f"{API}/v1/collections/{collection['collection_id']}/documents", headers=H
).json()
print(docs)Use Cases
Keep Building
Supported Input Formats
Quick Info
Run it over a library
Mixpeek runs this conversion as a pipeline over a whole library in your object storage, with the output landing as queryable documents. The reader on this page handles one file at a time.
Frequently Asked Questions
Ready to convert image to metadata?
Start using the Mixpeek Image to Metadata in minutes. Sign up for a free API key and follow the documentation to get started.