imagemeta is a high-performance Go library for extracting EXIF and XMP metadata from images and camera RAW formats.
It is built for:
imagehash)go get github.com/evanoberholster/imagemeta
.jpg, .jpeg.tif, .tiff, .cr2, .dng, .nef, .arw, .rw2.cr3, .heic, .heif, .avif.crwpackage main
import (
"fmt"
"os"
"github.com/evanoberholster/imagemeta"
)
func main() {
f, err := os.Open("image.jpg")
if err != nil {
panic(err)
}
defer f.Close()
ex, err := imagemeta.Decode(f)
if err != nil {
panic(err)
}
fmt.Println("type:", ex.ImageType)
fmt.Println("make:", ex.Make)
fmt.Println("model:", ex.Model)
fmt.Println("datetime:", ex.DateTimeOriginal)
}
Top-level decode entry points:
Decode(io.ReadSeeker)DecodeJPEG(io.ReadSeeker)DecodeTiff(io.ReadSeeker)DecodeCR3(io.ReadSeeker)DecodeCRW(io.ReadSeeker)DecodeHeif(io.ReadSeeker)DecodePng(io.ReadSeeker)PreviewCR3(io.ReadSeeker)Parse a sidecar .xmp file:
x, err := xmp.ParseXmp(file)
Parse embedded XMP from an image:
x, err := xmp.Parse(file)
Package: github.com/evanoberholster/imagemeta/meta/xmp
Use imagetype for quick format detection before decode:
t, err := imagetype.Scan(r)
Package: github.com/evanoberholster/imagemeta/imagetype
imagehash provides 64-bit and 256-bit perceptual hashing with low-allocation paths.
Package: github.com/evanoberholster/imagemeta/imagehash
bench_test.go| Benchmark | ns/op | B/op | allocs/op |
|---|---|---|---|
| Canon/CR2 | 6646 | 2440 | 20 |
| Canon/CR3 | 8015 | 3723 | 22 |
| Canon/JPG | 2058 | 176 | 9 |
| Nikon/JPG | 1747 | 104 | 7 |
| Nikon/NEF | 10306 | 736 | 19 |
| Sony/ARW | 6584 | 1512 | 12 |
Note: benchmark results vary by CPU, Go version, and sample files.
Pull requests and issue reports are welcome.
Before opening a PR, run:
go test ./...
golangci-lint run
imagemeta is heavily inspired and tested on:
rwcarlsen/goexifAdditional references:
go4 (BMFF/HEIF parser concepts)lclevy/canon_cr3MIT
$ claude mcp add imagemeta \
-- python -m otcore.mcp_server <graph>