Version: v1.0.0 Latest Latest

This package is not in the latest version of its module.

Go to latest
Published: Oct 7, 2020 License: BSD-2-Clause Imports: 13 Imported by: 1


To regenerate the regression test data, run go generate inside the exif package directory and commit the changes to regress_expected_test.go.



Package exif implements decoding of EXIF data as defined in the EXIF 2.2 specification (http://www.exif.org/Exif2-2.PDF).




View Source
const UnknownPrefix = "UnknownTag_"

UnknownPrefix is used as the first part of field names for decoded tags for which there is no known/supported EXIF field.


View Source
var (
	// NotFoundError is returned if EXIF information is not found in a JPEG input file.
	NotFoundError = errors.New("exif: failed to find exif intro marker")


func IsCriticalError

func IsCriticalError(err error) bool

IsCriticalError, given the error returned by Decode, reports whether the returned *Exif may contain usable information.

func IsExifError

func IsExifError(err error) bool

IsExifError reports whether the error happened while decoding the EXIF sub-IFD.

func IsGPSError

func IsGPSError(err error) bool

IsGPSError reports whether the error happened while decoding the GPS sub-IFD.

func IsInteroperabilityError

func IsInteroperabilityError(err error) bool

IsInteroperabilityError reports whether the error happened while decoding the Interoperability sub-IFD.

func IsShortReadTagValueError

func IsShortReadTagValueError(err error) bool

IsShortReadTagValueError identifies a ErrShortReadTagValue error.

func IsTagNotPresentError

func IsTagNotPresentError(err error) bool

func RegisterParsers

func RegisterParsers(ps ...Parser)

RegisterParsers registers one or more parsers to be automatically called when decoding EXIF data via the Decode function.


type Exif

type Exif struct {
	Tiff *tiff.Tiff

	Raw []byte
	// contains filtered or unexported fields

Exif provides access to decoded EXIF metadata fields and values.

func Decode

func Decode(r io.Reader) (*Exif, error)

Decode parses EXIF data from r (a TIFF, JPEG, or raw EXIF block) and returns a queryable Exif object. After the EXIF data section is called and the TIFF structure is decoded, each registered parser is called (in order of registration). If one parser returns an error, decoding terminates and the remaining parsers are not called.

The error can be inspected with functions such as IsCriticalError to determine whether the returned object might still be usable.

package main

import (


func main() {
	fname := "sample1.jpg"

	f, err := os.Open(fname)
	if err != nil {

	// Optionally register camera makenote data parsing - currently Nikon and
	// Canon are supported.

	x, err := exif.Decode(f)
	if err != nil {

	camModel, _ := x.Get(exif.Model) // normally, don't ignore errors!

	focal, _ := x.Get(exif.FocalLength)
	numer, denom, _ := focal.Rat2(0) // retrieve first (only) rat. value
	fmt.Printf("%v/%v", numer, denom)

	// Two convenience functions exist for date/time taken and GPS coords:
	tm, _ := x.DateTime()
	fmt.Println("Taken: ", tm)

	lat, long, _ := x.LatLong()
	fmt.Println("lat, long: ", lat, ", ", long)

func (*Exif) DateTime

func (x *Exif) DateTime() (time.Time, error)

DateTime returns the EXIF's "DateTimeOriginal" field, which is the creation time of the photo. If not found, it tries the "DateTime" (which is meant as the modtime) instead. The error will be TagNotPresentErr if none of those tags were found, or a generic error if the tag value was not a string, or the error returned by time.Parse.

If the EXIF lacks timezone information or GPS time, the returned time's Location will be time.Local.

func (*Exif) Get

func (x *Exif) Get(name FieldName) (*tiff.Tag, error)

Get retrieves the EXIF tag for the given field name.

If the tag is not known or not present, an error is returned. If the tag name is known, the error will be a TagNotPresentError.

func (*Exif) JpegThumbnail

func (x *Exif) JpegThumbnail() ([]byte, error)

JpegThumbnail returns the jpeg thumbnail if it exists. If it doesn't exist, TagNotPresentError will be returned

func (*Exif) LatLong

func (x *Exif) LatLong() (lat, long float64, err error)

LatLong returns the latitude and longitude of the photo and whether it was present.

func (*Exif) LoadTags

func (x *Exif) LoadTags(d *tiff.Dir, fieldMap map[uint16]FieldName, showMissing bool)

LoadTags loads tags into the available fields from the tiff Directory using the given tagid-fieldname mapping. Used to load makernote and other meta-data. If showMissing is true, tags in d that are not in the fieldMap will be loaded with the FieldName UnknownPrefix followed by the tag ID (in hex format).

func (Exif) MarshalJSON

func (x Exif) MarshalJSON() ([]byte, error)

MarshalJson implements the encoding/json.Marshaler interface providing output of all EXIF fields present (names and values).

func (*Exif) String

func (x *Exif) String() string

String returns a pretty text representation of the decoded exif data.

func (*Exif) TimeZone

func (x *Exif) TimeZone() (*time.Location, error)

func (*Exif) Walk

func (x *Exif) Walk(w Walker) error

Walk calls the Walk method of w with the name and tag for every non-nil EXIF field. If w aborts the walk with an error, that error is returned.

type FieldName

type FieldName string
const (
	ImageWidth                 FieldName = "ImageWidth"
	ImageLength                FieldName = "ImageLength" // Image height called Length by EXIF spec
	BitsPerSample              FieldName = "BitsPerSample"
	Compression                FieldName = "Compression"
	PhotometricInterpretation  FieldName = "PhotometricInterpretation"
	Orientation                FieldName = "Orientation"
	SamplesPerPixel            FieldName = "SamplesPerPixel"
	PlanarConfiguration        FieldName = "PlanarConfiguration"
	YCbCrSubSampling           FieldName = "YCbCrSubSampling"
	YCbCrPositioning           FieldName = "YCbCrPositioning"
	XResolution                FieldName = "XResolution"
	YResolution                FieldName = "YResolution"
	ResolutionUnit             FieldName = "ResolutionUnit"
	DateTime                   FieldName = "DateTime"
	ImageDescription           FieldName = "ImageDescription"
	Make                       FieldName = "Make"
	Model                      FieldName = "Model"
	Software                   FieldName = "Software"
	Artist                     FieldName = "Artist"
	Copyright                  FieldName = "Copyright"
	ExifIFDPointer             FieldName = "ExifIFDPointer"
	GPSInfoIFDPointer          FieldName = "GPSInfoIFDPointer"
	InteroperabilityIFDPointer FieldName = "InteroperabilityIFDPointer"
	ExifVersion                FieldName = "ExifVersion"
	FlashpixVersion            FieldName = "FlashpixVersion"
	ColorSpace                 FieldName = "ColorSpace"
	ComponentsConfiguration    FieldName = "ComponentsConfiguration"
	CompressedBitsPerPixel     FieldName = "CompressedBitsPerPixel"
	PixelXDimension            FieldName = "PixelXDimension"
	PixelYDimension            FieldName = "PixelYDimension"
	MakerNote                  FieldName = "MakerNote"
	UserComment                FieldName = "UserComment"
	RelatedSoundFile           FieldName = "RelatedSoundFile"
	DateTimeOriginal           FieldName = "DateTimeOriginal"
	DateTimeDigitized          FieldName = "DateTimeDigitized"
	SubSecTime                 FieldName = "SubSecTime"
	SubSecTimeOriginal         FieldName = "SubSecTimeOriginal"
	SubSecTimeDigitized        FieldName = "SubSecTimeDigitized"
	ImageUniqueID              FieldName = "ImageUniqueID"
	ExposureTime               FieldName = "ExposureTime"
	FNumber                    FieldName = "FNumber"
	ExposureProgram            FieldName = "ExposureProgram"
	SpectralSensitivity        FieldName = "SpectralSensitivity"
	ISOSpeedRatings            FieldName = "ISOSpeedRatings"
	OECF                       FieldName = "OECF"
	ShutterSpeedValue          FieldName = "ShutterSpeedValue"
	ApertureValue              FieldName = "ApertureValue"
	BrightnessValue            FieldName = "BrightnessValue"
	ExposureBiasValue          FieldName = "ExposureBiasValue"
	MaxApertureValue           FieldName = "MaxApertureValue"
	SubjectDistance            FieldName = "SubjectDistance"
	MeteringMode               FieldName = "MeteringMode"
	LightSource                FieldName = "LightSource"
	Flash                      FieldName = "Flash"
	FocalLength                FieldName = "FocalLength"
	SubjectArea                FieldName = "SubjectArea"
	FlashEnergy                FieldName = "FlashEnergy"
	SpatialFrequencyResponse   FieldName = "SpatialFrequencyResponse"
	FocalPlaneXResolution      FieldName = "FocalPlaneXResolution"
	FocalPlaneYResolution      FieldName = "FocalPlaneYResolution"
	FocalPlaneResolutionUnit   FieldName = "FocalPlaneResolutionUnit"
	SubjectLocation            FieldName = "SubjectLocation"
	ExposureIndex              FieldName = "ExposureIndex"
	SensingMethod              FieldName = "SensingMethod"
	FileSource                 FieldName = "FileSource"
	SceneType                  FieldName = "SceneType"
	CFAPattern                 FieldName = "CFAPattern"
	CustomRendered             FieldName = "CustomRendered"
	ExposureMode               FieldName = "ExposureMode"
	WhiteBalance               FieldName = "WhiteBalance"
	DigitalZoomRatio           FieldName = "DigitalZoomRatio"
	FocalLengthIn35mmFilm      FieldName = "FocalLengthIn35mmFilm"
	SceneCaptureType           FieldName = "SceneCaptureType"
	GainControl                FieldName = "GainControl"
	Contrast                   FieldName = "Contrast"
	Saturation                 FieldName = "Saturation"
	Sharpness                  FieldName = "Sharpness"
	DeviceSettingDescription   FieldName = "DeviceSettingDescription"
	SubjectDistanceRange       FieldName = "SubjectDistanceRange"
	LensMake                   FieldName = "LensMake"
	LensModel                  FieldName = "LensModel"

Primary EXIF fields

const (
	XPTitle    FieldName = "XPTitle"
	XPComment  FieldName = "XPComment"
	XPAuthor   FieldName = "XPAuthor"
	XPKeywords FieldName = "XPKeywords"
	XPSubject  FieldName = "XPSubject"

Windows-specific tags

const (
	ThumbJPEGInterchangeFormat       FieldName = "ThumbJPEGInterchangeFormat"       // offset to thumb jpeg SOI
	ThumbJPEGInterchangeFormatLength FieldName = "ThumbJPEGInterchangeFormatLength" // byte length of thumb

thumbnail fields

const (
	GPSVersionID        FieldName = "GPSVersionID"
	GPSLatitudeRef      FieldName = "GPSLatitudeRef"
	GPSLatitude         FieldName = "GPSLatitude"
	GPSLongitudeRef     FieldName = "GPSLongitudeRef"
	GPSLongitude        FieldName = "GPSLongitude"
	GPSAltitudeRef      FieldName = "GPSAltitudeRef"
	GPSAltitude         FieldName = "GPSAltitude"
	GPSTimeStamp        FieldName = "GPSTimeStamp"
	GPSSatelites        FieldName = "GPSSatelites"
	GPSStatus           FieldName = "GPSStatus"
	GPSMeasureMode      FieldName = "GPSMeasureMode"
	GPSDOP              FieldName = "GPSDOP"
	GPSSpeedRef         FieldName = "GPSSpeedRef"
	GPSSpeed            FieldName = "GPSSpeed"
	GPSTrackRef         FieldName = "GPSTrackRef"
	GPSTrack            FieldName = "GPSTrack"
	GPSImgDirectionRef  FieldName = "GPSImgDirectionRef"
	GPSImgDirection     FieldName = "GPSImgDirection"
	GPSMapDatum         FieldName = "GPSMapDatum"
	GPSDestLatitudeRef  FieldName = "GPSDestLatitudeRef"
	GPSDestLatitude     FieldName = "GPSDestLatitude"
	GPSDestLongitudeRef FieldName = "GPSDestLongitudeRef"
	GPSDestLongitude    FieldName = "GPSDestLongitude"
	GPSDestBearingRef   FieldName = "GPSDestBearingRef"
	GPSDestBearing      FieldName = "GPSDestBearing"
	GPSDestDistanceRef  FieldName = "GPSDestDistanceRef"
	GPSDestDistance     FieldName = "GPSDestDistance"
	GPSProcessingMethod FieldName = "GPSProcessingMethod"
	GPSAreaInformation  FieldName = "GPSAreaInformation"
	GPSDateStamp        FieldName = "GPSDateStamp"
	GPSDifferential     FieldName = "GPSDifferential"

GPS fields

const (
	InteroperabilityIndex FieldName = "InteroperabilityIndex"

interoperability fields

type Parser

type Parser interface {
	// Parse should read data from x and insert parsed fields into x via
	// LoadTags.
	Parse(x *Exif) error

Parser allows the registration of custom parsing and field loading in the Decode function.

type TagNotPresentError

type TagNotPresentError FieldName

A TagNotPresentError is returned when the requested field is not present in the EXIF.

func (TagNotPresentError) Error

func (tag TagNotPresentError) Error() string

type Walker

type Walker interface {
	// Walk is called for each non-nil EXIF field. Returning a non-nil
	// error aborts the walk/traversal.
	Walk(name FieldName, tag *tiff.Tag) error

Walker is the interface used to traverse all fields of an Exif object.

Source Files

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL