• Stars
    star
    491
  • Rank 89,636 (Top 2 %)
  • Language
    Go
  • License
    MIT License
  • Created over 6 years ago
  • Updated 8 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A very complete, highly tested, standards-driven (but customizable) EXIF reader/writer lovingly written in Go.

Build Status codecov Go Report Card GoDoc

Overview

This package provides native Go functionality to parse an existing EXIF block, update an existing EXIF block, or add a new EXIF block.

Getting

To get the project and dependencies:

$ go get -t github.com/dsoprea/go-exif/v3

Requirements

  • Go >= 1.17: Due to a breakage with "go test", we only officially support 1.17 for testing/CI reasons. It may still work in earlier versions if such a need is critically required, however.

Scope

This project is concerned only with parsing and encoding raw EXIF data. It does not understand specific file-formats. This package assumes you know how to extract the raw EXIF data from a file, such as a JPEG, and, if you want to update it, know how to write it back. File-specific formats are not the concern of go-exif, though we provide exif.SearchAndExtractExif and exif.SearchFileAndExtractExif as brute-force search mechanisms that will help you explore the EXIF information for newer formats that you might not yet have any way to parse.

That said, the author also provides the following projects to support the efficient processing of the corresponding image formats:

See the SetExif example in go-jpeg-image-structure for practical information on getting started with JPEG files.

Usage

The package provides a set of working examples and is covered by unit-tests. Please look to these for getting familiar with how to read and write EXIF.

Create an instance of the Exif type and call Scan() with a byte-slice, where the first byte is the beginning of the raw EXIF data. You may pass a callback that will be invoked for every tag or nil if you do not want one. If no callback is given, you are effectively just validating the structure or parsing of the image.

Obviously, it is most efficient to properly parse the media file and then provide the specific EXIF data to be parsed, but there is also a heuristic for finding the EXIF data within the media blob, directly. This means that, at least for testing or curiosity, you do not have to parse or even understand the format of image or audio file in order to find and decode the EXIF information inside of it. See the usage of the SearchAndExtractExif method in the example.

The library often refers to an IFD with an "IFD path" (e.g. IFD/Exif, IFD/GPSInfo). A "fully-qualified" IFD-path is one that includes an index describing which specific sibling IFD is being referred to if not the first one (e.g. IFD1, the IFD where the thumbnail is expressed per the TIFF standard).

There is an "IFD mapping" and a "tag index" that must be created and passed to the library from the top. These contain all of the knowledge of the IFD hierarchies and their tag-IDs (the IFD mapping) and the tags that they are allowed to host (the tag index). There are convenience functions to load them with the standard TIFF information, but you, alternatively, may choose something totally different (to support parsing any kind of EXIF data that does not follow or is not relevant to TIFF at all).

Standards and Customization

This project is configuration driven. By default, it has no knowledge of tags and IDs until you load them prior to using (which is incorporated in the examples). You are just as easily able to add additional custom IFDs and custom tags for them. If desired, you could completely ignore the standard information and load totally non-standard IFDs and tags.

This would be useful for divergent implementations that add non-standard information to images. It would also be useful if there is some need to just store a flat list of tags in an image for simplified, proprietary usage.

Reader Tool

There is a runnable reading/dumping tool included:

$ go get github.com/dsoprea/go-exif/v3/command/exif-read-tool
$ exif-read-tool --filepath "<media file-path>"

Example output:

IFD-PATH=[IFD] ID=(0x010f) NAME=[Make] COUNT=(6) TYPE=[ASCII] VALUE=[Canon]
IFD-PATH=[IFD] ID=(0x0110) NAME=[Model] COUNT=(22) TYPE=[ASCII] VALUE=[Canon EOS 5D Mark III]
IFD-PATH=[IFD] ID=(0x0112) NAME=[Orientation] COUNT=(1) TYPE=[SHORT] VALUE=[1]
IFD-PATH=[IFD] ID=(0x011a) NAME=[XResolution] COUNT=(1) TYPE=[RATIONAL] VALUE=[72/1]
IFD-PATH=[IFD] ID=(0x011b) NAME=[YResolution] COUNT=(1) TYPE=[RATIONAL] VALUE=[72/1]
IFD-PATH=[IFD] ID=(0x0128) NAME=[ResolutionUnit] COUNT=(1) TYPE=[SHORT] VALUE=[2]
IFD-PATH=[IFD] ID=(0x0132) NAME=[DateTime] COUNT=(20) TYPE=[ASCII] VALUE=[2017:12:02 08:18:50]
...

You can also print the raw, parsed data as JSON:

$ exif-read-tool --filepath "<media file-path>" -json

Example output:

[
    {
        "ifd_path": "IFD",
        "fq_ifd_path": "IFD",
        "ifd_index": 0,
        "tag_id": 271,
        "tag_name": "Make",
        "tag_type_id": 2,
        "tag_type_name": "ASCII",
        "unit_count": 6,
        "value": "Canon",
        "value_string": "Canon"
    },
    {
        "ifd_path": "IFD",
...

Testing

The traditional method:

$ go test github.com/dsoprea/go-exif/v3/...

Release Notes

v3 Release

This release primarily introduces an interchangeable data-layer, where any io.ReadSeeker can be used to read EXIF data rather than necessarily loading the EXIF blob into memory first.

Several backwards-incompatible clean-ups were also included in this release. See releases for more information.

v2 Release

Features a heavily reflowed interface that makes usage much simpler. The undefined-type tag-processing (which affects most photographic images) has also been overhauled and streamlined. It is now complete and stable. Adoption is strongly encouraged.

Contributing

EXIF has an excellently-documented structure but there are a lot of devices and manufacturers out there. There are only so many files that we can personally find to test against, and most of these are images that have been generated only in the past few years. JPEG, being the largest implementor of EXIF, has been around for even longer (but not much). Therefore, there is a lot of compatibility to test for.

If you are able to help by running the included reader-tool against all of the EXIF-compatible files you have, it would be deeply appreciated. This is mostly going to be JPEG files (but not all variations). If you are able to test a large number of files (thousands or millions) then please post an issue mentioning how many files you have processed. If you had failures, then please share them and try to support efforts to understand them.

If you are able to test 100K+ files, I will give you credit on the project. The further back in time your images reach, the higher in the list your name/company will go.

Contributors/Testing

Thank you to the following users for solving non-trivial issues, supporting the project with solving edge-case problems in specific images, or otherwise providing their non-trivial time or image corpus to test go-exif:

In addition to these, it has been tested on my own collection, north of 560K images.

More Repositories

1

GDriveFS

An innovative FUSE wrapper for Google Drive.
Python
663
star
2

PyInotify

An efficient and elegant inotify (Linux filesystem activity monitor) library for Python. Python 2 and 3 compatible.
Python
240
star
3

PySvn

Lightweight Subversion library for Python.
Python
215
star
4

PyEasyArchive

A very intuitive and useful adapter to libarchive for universal archive access.
Python
97
star
5

go-jpeg-image-structure

Parse JPEG data into segments via code or CLI from pure Go. Read/export/write EXIF data. Read XMP and IPTC metadata.
Go
69
star
6

go-ext4

A pure Go implementation of an ext4 reader with journaling support that does not require the kernel nor privileged access.
Go
43
star
7

Snackwich

A Snack-based Python console UI that reads screen configurations from a file.
Python
27
star
8

TightOCR

A slim, non-SWIG Python adapter to CTesseract (Tesseract OCR for C).
Python
24
star
9

GeonamesRdf

A Python client for the RDF web-services provided by Geonames (http://www.geonames.org).
Python
22
star
10

go-png-image-structure

Read/write PNGs as well as the EXIF in PNGs from pure Go.
Go
22
star
11

go-perceptualhash

Blockhash perceptual-hash algorithm for images. Written in pure Go.
Go
21
star
12

PythonEtcdClient

A simple and efficient etcd client that exposes all functions and just works.
Python
21
star
13

M2CryptoWindows

Binaries for Python 2.7 M2Crypto under Windows
19
star
14

go-exfat

exFAT reader implementation based on Microsoft specifications.
Go
18
star
15

PySecure

A complete Python SSH/SFTP library based on libssh.
Python
18
star
16

go-exif-knife

Perform surgical operations on EXIF data at the command-line with JPG, PNG, HEIC, and TIFF files.
Go
17
star
17

RandomUtility

Disparate tools by published by Dustin.
Python
14
star
18

TinyUntar

A tiny untar library written in C.
C
14
star
19

GeditSafetySave

Automatically store unsaved documents to a temporary location under the current user's home. This keeps your documents, temporary to-do lists, etc.. safe from crashes.
Python
14
star
20

CTesseract

A C adapter for the C++ Tesseract OCR Library (Google).
C++
13
star
21

go-fuse-example

A minimal, browseable, read-only, memory-based filesystem in Go.
Go
12
star
22

RijndaelPbkdf

Pure-Python Rijndael and PBKDF2 package. Python2 and Python3 compatible.
Python
12
star
23

CodeMirrorRemoteValidator

An asynchronous CodeMirror lint plugin that will receive code, send it to a callback (that can send it somewhere via Ajax, etc..), and apply any discovered errors on return.
JavaScript
12
star
24

go-appengine-sessioncascade

Equip Go with session support under Google AppEngine. Implement one or more AppEngine-specific backends, such as Memcache and Datastore, to store your session data.
Go
12
star
25

go-heic-exif-extractor

Parses an HEIC image and returns an EXIF accessor (if an EXIF blob is present).
Go
11
star
26

youtube-autodownloader

Monitor YouTube playlists and automatically download newly-added videos.
Python
11
star
27

PyHdHomeRun

Python interface to HDHomeRun network-attached TV tuners.
Python
10
star
28

ChromeIdGenerator

A tiny tool to generate Google Chrome extension IDs from an extension's public-key.
Python
9
star
29

PySchedules

Schedules Direct library for Python. Provides event-driven hooks for lineup, station, channel map, schedule, program, cast/crew, and genre data. Also provides QAM map (channels.conf) data. Go wild.
Python
9
star
30

ApnsPlistCsr

Tool to produce encoded Plists/CSRs for APNS.
Python
9
star
31

protobufp

Adds the stream-processing to protobuf messaging that you usually need to add yourself.
Python
8
star
32

go-exiftool

List EXIF tags, set EXIF tags, and extract thumbnails in images using Go.
Go
7
star
33

PythonUpstart

An intuitive library interface to Upstart for service and job management.
Python
7
star
34

go-iptc

Parse IPTC metadata with pure Go
Go
6
star
35

JobX

JobExchange is a distributed Python-Based MapReduce solution.
Python
5
star
36

M2CryptoWin64

An installable M2Crypto Python package for 64-bit Windows systems.
Python
5
star
37

SslApi

An SOA certificate authority (CA).
Python
5
star
38

go-time-parse

Parse time phrases into Go durations.
Go
5
star
39

M2CryptoWin32

An installable M2Crypto Python package for 32-bit Windows systems.
Python
5
star
40

go-logging

Useful and awesome logging system for Go with prefixing and stacktraces.
Go
5
star
41

RestPipe

An SSL-authenticated, durable, bidirectional, RESTful, client-server pipe that transports custom events.
Python
5
star
42

ZapLib

A C library of uniform DVB tuning calls for ATSC (US), DVB-C (cable), DVB-S (satellite), DVB-T (terrestrial). Based on dvb-apps.
C
5
star
43

markdown-embedimages

Translate markdown to HTML and encode/embed images into the HTML.
Python
5
star
44

go-parallel-walker

CURRENTLY IN ACTIVE DEVELOPMENT - A simple, tuneable Go package and CLI tool to quickly walk a filesystem using a concurrently-processed job queue.
Go
4
star
45

RelayServer

A service that that acts as a single proxy between many individual clients and many instances of a server. As the clients initiate connections to the relay server, this solution defeats NAT.
Python
4
star
46

heic-exif-samples

Samples of HEIC images with EXIF. At this point in time they're non-trivial to find in the wild.
4
star
47

AwsDynDns

Update your Route53-hosted domain name with your public IP.
Python
4
star
48

CaKit

A light project that conveniently bundles the logic needed to build both example CA certificates and a signed, example certificate.
Python
4
star
49

DtcLookup

A webpage-based database for automotive diagnostic trouble codes (DTC's).
Python
4
star
50

time-to-go

Efficiently store, scan, retrieve, update, and add time-series blobs on a filesystem.
Go
4
star
51

YiiBash

Add Bash command completion to your PHP Yii project.
PHP
4
star
52

GlacierTool

A simple tool to do massive uploads to Amazon Glacier
Python
4
star
53

PyZap

Python wrapper for ZapLib digital television (DVB) tuning library.
Python
4
star
54

go-tiff-image-structure

Parse TIFF data for EXIF metadata
Go
4
star
55

JsonPare

A very simple utility to decode and unwind JSON into JSON from the command-line.
Python
4
star
56

SMARTOnFHIRExample

A working example of how to read FHIR health data from a SMART resource and plot aggregate vital signs (all patients).
Python
4
star
57

go-xmp

Parse XMP documents (for image-metadata) with pure Go.
Go
4
star
58

go-utility

Reusable tools.
Go
3
star
59

go-geographic-attractor

Efficiently identify the nearest major city to a given coordinate.
Go
3
star
60

python-googleautoauth

Dramatically reduces the complexity of the Google API authentication/authorization process in command-line tools.
Python
3
star
61

go-appengine-logging

Configuration-based AppEngine logging library with level control, filters, and pluggable, interface-based writers.
Go
3
star
62

go-geographic-index

An in-memory time-series index that can be populated manually and/or by recursively processing a path.
Go
3
star
63

go-gpx

Easily and efficiently processing GPX (geographic track/log) data from Go.
Go
3
star
64

go-time-index

A simple Go package to manage time-series with data and slices of time-intervals with data.
Go
3
star
65

go-geographic-autogroup-images

A package that knows how to take a list of locations, a list of images, knowledge of EXIF, and some geographic/population data (if any images are not already geotagged), and group images by the major cities that they were taken near.
Go
3
star
66

HuffmanExample

Shows how to build a tree, establish an encoding, encode the data, preorder-serialize the binary tree, combine the tree and data to render complete file-data, and reverse the process.
Python
3
star
67

go-s2

A tool that can convert between coordinates, S2 cells, and S2 tokens, print cell info, and generate KML visualizations of cell parents and boundaries.
Go
2
star
68

go-napster-to-spotify-sync

Install tracks from Napster favorites to a Spotify playlist by one or more artists.
Go
2
star
69

go-pathfingerprint

Recursively calculate a SHA1 or SHA256 hash for a given directory.
Go
2
star
70

SvnCl

A one-line command to streamline building a Subversion changelog for tag/release messages.
Python
2
star
71

go-napster

A Go client for Napster/Rhapsody.
Go
2
star
72

TabManiac

Automatically back-up your Chrome tabs, and maintain a history of backups.
JavaScript
2
star
73

go-efficient-json-reader

Easily, efficiently, iteratively parse massive JSON data structures.
Go
2
star
74

RWebApplicationExample

An example Rook-based R web application
HTML
2
star
75

PySynchronousGlacier

Execute synchronous workflows against Amazon Glacier.
Python
2
star
76

bracketed-image-finder

Determine groups of images that were produced by bracketed image capture (e.g. Sony cameras)
Python
2
star
77

omsa-alert

Send emails or call commands when there are controller/disk problems reported by the Dell OMSA omreport command-line tool.
Python
2
star
78

go-photoshop-info-format

Minimal Photoshop format implementation. Currently only provides parsing functionality to expose embedded IPTC data.
Go
2
star
79

PathScan

A parallellized filesystem scanning, filtering, and processing framework (iteration 3).
Python
2
star
80

go-webp-image-structure

Parse WEBP RIFF stream and expose EXIF data via pure Go.
Go
2
star
81

HookableWebServer

A tiny C++ (mostly C) web-server that calls function pointers for requests and logging. Based on IBM's open-source small "nweb" web server..
C++
2
star
82

go-github-reminders

A tool that determines what Github issues you are currently involved in and reminds you about issues you are overdue in responding to.
Go
2
star
83

RemoteImageBrowser

Allows you to efficiently browse a large image-file hierarchy from a website with thumbnails (cached) and lightboxes.
JavaScript
2
star
84

LicensePrepend

Make sure all your source files have the standard licensing stub at the top.
Python
2
star
85

BeanTool

A console tool for querying a beanstalkd queue.
Python
2
star
86

MpegTsScanner

Library to scan packets from an MPEG-TS file. Also provides a call to grab information on the first program found. This latter feature is useful for getting information (subtitle info, etc..) for a program recorded from an ATSC/DVB television tuner. Depends on the LIBDVBPSI library (from the VLC project).
C
2
star
87

WebsocketServer

A reference implementation for a WebSocket server and two sample clients. Tested under Firefox 13 and Chrome 20.
PHP
2
star
88

go-gpxreader

Easily and efficiently processing GPX (geographic track/log) data from Go. PROJECT IS DEPRECATED. PLEASE USE go-gpx/reader.
Go
2
star
89

tree_partition

Partition a large file tree into several file trees of symlinks having equal file counts
Python
2
star
90

go-index-audit

A tool to wait on the Go Proxy to propagate your recent changes before returning
Go
1
star
91

pathhistogram

Generate a histogram of file-sizes within a path. Can also set constraints and write-out the bins.
Python
1
star
92

go-gpsbabel

A wrapper around GPSBabel to allow idiomatic Go to be used to interact with it.
Go
1
star
93

bingrok

A surgical tool for exploring structured binary data
Python
1
star
94

go-exif-extra

Higher-level EXIF and image functionality that works universally across many image formats.
Go
1
star
95

go-http-lifecycle-router

A simple HTTP handler suite that can trigger lifecycle events before and after requests are handled.
Go
1
star
96

PypiStats

A jQuery plugin to display a PyPI package's download statistics.
JavaScript
1
star
97

go-gpx-distance

Count the kilometers traveled in GPX data
Go
1
star
98

PythonScheduler

A multithreaded task scheduler that can schedule Python routines to run either at a particular time or at a particular interval.
Python
1
star
99

elasticbeanstalk-test

Go
1
star
100

MpoJpegFlatten

Convert 3D MPO JPEGs to normal images with a single left-right image.
C++
1
star