lens @ d5261d7f121985f13f9d19e9efd5c2ae3d4b5609

  1package fileop
  2
  3import (
  4	"math"
  5	"time"
  6
  7	"github.com/barasher/go-exiftool"
  8
  9	"git.sr.ht/~gabrielgio/img/pkg/components/media"
 10)
 11
 12func ReadExif(path string) (*media.MediaEXIF, error) {
 13	et, err := exiftool.NewExiftool()
 14	if err != nil {
 15		return nil, err
 16	}
 17	defer et.Close()
 18
 19	newExif := &media.MediaEXIF{}
 20	fileInfo := et.ExtractMetadata(path)[0]
 21
 22	// Get description
 23	description, err := fileInfo.GetString("ImageDescription")
 24	if err == nil {
 25		newExif.Description = &description
 26	}
 27
 28	// Get camera model
 29	model, err := fileInfo.GetString("Model")
 30	if err == nil {
 31		newExif.Camera = &model
 32	}
 33
 34	// Get Camera make
 35	make, err := fileInfo.GetString("Make")
 36	if err == nil {
 37		newExif.Maker = &make
 38	}
 39
 40	// Get lens
 41	lens, err := fileInfo.GetString("LensModel")
 42	if err == nil {
 43		newExif.Lens = &lens
 44	}
 45
 46	//Get time of photo
 47	createDateKeys := []string{
 48		"CreationDate",
 49		"DateTimeOriginal",
 50		"CreateDate",
 51		"TrackCreateDate",
 52		"MediaCreateDate",
 53		"FileCreateDate",
 54		"ModifyDate",
 55		"TrackModifyDate",
 56		"MediaModifyDate",
 57		"FileModifyDate",
 58	}
 59	for _, createDateKey := range createDateKeys {
 60		date, err := fileInfo.GetString(createDateKey)
 61		if err == nil {
 62			layout := "2006:01:02 15:04:05"
 63			dateTime, err := time.Parse(layout, date)
 64			if err == nil {
 65				newExif.DateShot = &dateTime
 66			} else {
 67				layoutWithOffset := "2006:01:02 15:04:05+02:00"
 68				dateTime, err = time.Parse(layoutWithOffset, date)
 69				if err == nil {
 70					newExif.DateShot = &dateTime
 71				}
 72			}
 73			break
 74		}
 75	}
 76
 77	// Get exposure time
 78	exposureTime, err := fileInfo.GetFloat("ExposureTime")
 79	if err == nil {
 80		newExif.Exposure = &exposureTime
 81	}
 82
 83	// Get aperture
 84	aperture, err := fileInfo.GetFloat("Aperture")
 85	if err == nil {
 86		newExif.Aperture = &aperture
 87	}
 88
 89	// Get ISO
 90	iso, err := fileInfo.GetInt("ISO")
 91	if err == nil {
 92		newExif.Iso = &iso
 93	}
 94
 95	// Get focal length
 96	focalLen, err := fileInfo.GetFloat("FocalLength")
 97	if err == nil {
 98		newExif.FocalLength = &focalLen
 99	}
100
101	// Get flash info
102	flash, err := fileInfo.GetInt("Flash")
103	if err == nil {
104		newExif.Flash = &flash
105	}
106
107	// Get orientation
108	orientation, err := fileInfo.GetInt("Orientation")
109	if err == nil {
110		newExif.Orientation = &orientation
111	}
112
113	// Get exposure program
114	expProgram, err := fileInfo.GetInt("ExposureProgram")
115	if err == nil {
116		newExif.ExposureProgram = &expProgram
117	}
118
119	// GPS coordinates - longitude
120	longitudeRaw, err := fileInfo.GetFloat("GPSLongitude")
121	if err == nil {
122		newExif.GPSLongitude = &longitudeRaw
123	}
124
125	// GPS coordinates - latitude
126	latitudeRaw, err := fileInfo.GetFloat("GPSLatitude")
127	if err == nil {
128		newExif.GPSLatitude = &latitudeRaw
129	}
130
131	sanitizeEXIF(newExif)
132
133	return newExif, nil
134}
135
136// isFloatReal returns true when the float value represents a real number
137// (different than +Inf, -Inf or NaN)
138func isFloatReal(v float64) bool {
139	if math.IsInf(v, 1) {
140		return false
141	} else if math.IsInf(v, -1) {
142		return false
143	} else if math.IsNaN(v) {
144		return false
145	}
146	return true
147}
148
149// sanitizeEXIF removes any EXIF float64 field that is not a real number (+Inf,
150// -Inf or Nan)
151func sanitizeEXIF(exif *media.MediaEXIF) {
152	if exif.Exposure != nil && !isFloatReal(*exif.Exposure) {
153		exif.Exposure = nil
154	}
155	if exif.Aperture != nil && !isFloatReal(*exif.Aperture) {
156		exif.Aperture = nil
157	}
158	if exif.FocalLength != nil && !isFloatReal(*exif.FocalLength) {
159		exif.FocalLength = nil
160	}
161	if (exif.GPSLatitude != nil && !isFloatReal(*exif.GPSLatitude)) ||
162		(exif.GPSLongitude != nil && !isFloatReal(*exif.GPSLongitude)) {
163		exif.GPSLatitude = nil
164		exif.GPSLongitude = nil
165	}
166}