Fast, dependency-free image metadata extraction for Go. Extract EXIF, IPTC, XMP, and ICC color profile data from images.
- Zero dependencies - Pure Go, stdlib only, no CGO
- Streaming I/O - Memory efficient, never loads entire files
- Multiple formats - JPEG (more formats coming soon)
- Multiple metadata types - EXIF, IPTC, XMP, ICC profiles
go get github.com/gomantics/imxgo install github.com/gomantics/imx/cmd/imx@latestpackage main
import (
"fmt"
"log"
"github.com/gomantics/imx"
)
func main() {
// Extract metadata from a file
meta, err := imx.MetadataFromFile("photo.jpg")
if err != nil {
log.Fatal(err)
}
// Access common EXIF tags using constants
if tag, ok := meta.Tag(imx.TagMake); ok {
fmt.Printf("Camera: %v\n", tag.Value)
}
if tag, ok := meta.Tag(imx.TagModel); ok {
fmt.Printf("Model: %v\n", tag.Value)
}
if tag, ok := meta.Tag(imx.TagDateTimeOriginal); ok {
fmt.Printf("Date: %v\n", tag.Value)
}
}These package-level functions use a shared default extractor and are safe for concurrent use. All functions accept optional configuration:
// From file path
meta, err := imx.MetadataFromFile("photo.jpg")
// From io.Reader
meta, err := imx.MetadataFromReader(reader)
// From byte slice
meta, err := imx.MetadataFromBytes(data)
// From URL
meta, err := imx.MetadataFromURL("https://example.com/photo.jpg")
// With options
meta, err := imx.MetadataFromFile("photo.jpg",
imx.WithMaxBytes(5<<20), // Limit to 5MB
imx.WithBufferSize(64*1024), // 64KB buffer
)For more control or when processing many files, create a reusable Extractor.
extractor := imx.New(
imx.WithMaxBytes(10<<20), // Limit to 10MB
imx.WithBufferSize(128*1024), // 128KB buffer
imx.WithStopOnFirstError(true), // Stop on first parser error
imx.WithHTTPTimeout(30*time.Second), // HTTP timeout for URLs
)
meta, err := extractor.MetadataFromFile("photo.jpg")// Iterate all tags
meta.Each(func(dir imx.Directory, tag imx.Tag) bool {
fmt.Printf("%s:%s = %v\n", dir.Name, tag.Name, tag.Value)
return true // continue iteration
})
// Iterate tags in a specific spec
meta.EachInSpec(imx.SpecEXIF, func(tag imx.Tag) bool {
fmt.Printf("%s = %v\n", tag.Name, tag.Value)
return true
})// Get multiple tags at once
values := meta.GetAll(imx.TagMake, imx.TagModel, imx.TagISO)
for id, value := range values {
fmt.Printf("%s: %v\n", id, value)
}| Spec | Description | Status |
|---|---|---|
| EXIF | Exchangeable Image File Format - camera settings, GPS coordinates, timestamps, and device information embedded by cameras and smartphones | ✅ Full support |
| IPTC | International Press Telecommunications Council - industry standard for news and media metadata including captions, credits, and keywords | ✅ Full support |
| XMP | Extensible Metadata Platform - Adobe's XML-based format for extensible metadata used by creative applications | ✅ Full support |
| ICC | International Color Consortium - color profile data describing color space characteristics for accurate color reproduction | ✅ Full support |
| Format | Status |
|---|---|
| JPEG | ✅ Full support |
| PNG | 🔜 Planned |
| WebP | 🔜 Planned |
| TIFF | 🔜 Planned |
| HEIF/HEIC | 🔜 Planned |
| AVIF | 🔜 Planned |
# Basic extraction
imx photo.jpg
# JSON output
imx --format json photo.jpg
# Filter by spec
imx --spec exif photo.jpg
# Get specific tag
imx --tag Make photo.jpg
# Process multiple files
imx --recursive ./photos/
# Read from stdin
cat photo.jpg | imx --stdinimx is designed for high performance:
- Streaming - Uses
bufio.Reader, never loads entire files into memory - Minimal allocations - Reuses buffers where possible
- Early termination - Stops parsing after metadata segments
- Concurrent safe - Extractor can be shared across goroutines
Latest Results (Apple M4 Pro, Go 1.23):
High-Level API
BenchmarkMetadataFromFile-12 12282 195814 ns/op 446581 B/op 2390 allocs/op
BenchmarkMetadataFromBytes-12 14323 167753 ns/op 446282 B/op 2388 allocs/op
BenchmarkMetadataFromReader-12 14336 168602 ns/op 446283 B/op 2388 allocs/op
BenchmarkMetadata_Tag-12 321816780 7.207 ns/op 0 B/op 0 allocs/op
BenchmarkMetadata_GetAll-12 35377401 68.13 ns/op 0 B/op 0 allocs/op
BenchmarkMetadata_Each-12 1884883 1294 ns/op 0 B/op 0 allocs/op
Parser Benchmarks
BenchmarkEXIFParse-12 2799916 870.9 ns/op 1552 B/op 26 allocs/op
BenchmarkIPTCParse-12 1767890 1325 ns/op 4506 B/op 46 allocs/op
BenchmarkXMPParse-12 119239 18799 ns/op 21888 B/op 355 allocs/op
BenchmarkICCParse-12 502302393 4.574 ns/op 0 B/op 0 allocs/op
BenchmarkJPEGParse-12 764920 2631 ns/op 47920 B/op 24 allocs/op
Continuous Benchmarking: Performance is automatically tracked on every commit to main. View historical trends and charts at:
Run locally: make bench
See CONTRIBUTING.md for detailed benchmarking information
Contributions are welcome! Please see CONTRIBUTING.md for development guidelines
MIT License - see LICENSE for details.