diff options
Diffstat (limited to 'pkg/fileop')
-rw-r--r-- | pkg/fileop/exif.go | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/pkg/fileop/exif.go b/pkg/fileop/exif.go new file mode 100644 index 0000000..48e495c --- /dev/null +++ b/pkg/fileop/exif.go @@ -0,0 +1,165 @@ +package fileop + +import ( + "math" + "time" + + "git.sr.ht/~gabrielgio/img/pkg/components/media" + "github.com/barasher/go-exiftool" +) + +func ReadExif(path string) (*media.MediaEXIF, error) { + et, err := exiftool.NewExiftool() + if err != nil { + return nil, err + } + defer et.Close() + + newExif := &media.MediaEXIF{} + fileInfo := et.ExtractMetadata(path)[0] + + // Get description + description, err := fileInfo.GetString("ImageDescription") + if err == nil { + newExif.Description = &description + } + + // Get camera model + model, err := fileInfo.GetString("Model") + if err == nil { + newExif.Camera = &model + } + + // Get Camera make + make, err := fileInfo.GetString("Make") + if err == nil { + newExif.Maker = &make + } + + // Get lens + lens, err := fileInfo.GetString("LensModel") + if err == nil { + newExif.Lens = &lens + } + + //Get time of photo + createDateKeys := []string{ + "CreationDate", + "DateTimeOriginal", + "CreateDate", + "TrackCreateDate", + "MediaCreateDate", + "FileCreateDate", + "ModifyDate", + "TrackModifyDate", + "MediaModifyDate", + "FileModifyDate", + } + for _, createDateKey := range createDateKeys { + date, err := fileInfo.GetString(createDateKey) + if err == nil { + layout := "2006:01:02 15:04:05" + dateTime, err := time.Parse(layout, date) + if err == nil { + newExif.DateShot = &dateTime + } else { + layoutWithOffset := "2006:01:02 15:04:05+02:00" + dateTime, err = time.Parse(layoutWithOffset, date) + if err == nil { + newExif.DateShot = &dateTime + } + } + break + } + } + + // Get exposure time + exposureTime, err := fileInfo.GetFloat("ExposureTime") + if err == nil { + newExif.Exposure = &exposureTime + } + + // Get aperture + aperture, err := fileInfo.GetFloat("Aperture") + if err == nil { + newExif.Aperture = &aperture + } + + // Get ISO + iso, err := fileInfo.GetInt("ISO") + if err == nil { + newExif.Iso = &iso + } + + // Get focal length + focalLen, err := fileInfo.GetFloat("FocalLength") + if err == nil { + newExif.FocalLength = &focalLen + } + + // Get flash info + flash, err := fileInfo.GetInt("Flash") + if err == nil { + newExif.Flash = &flash + } + + // Get orientation + orientation, err := fileInfo.GetInt("Orientation") + if err == nil { + newExif.Orientation = &orientation + } + + // Get exposure program + expProgram, err := fileInfo.GetInt("ExposureProgram") + if err == nil { + newExif.ExposureProgram = &expProgram + } + + // GPS coordinates - longitude + longitudeRaw, err := fileInfo.GetFloat("GPSLongitude") + if err == nil { + newExif.GPSLongitude = &longitudeRaw + } + + // GPS coordinates - latitude + latitudeRaw, err := fileInfo.GetFloat("GPSLatitude") + if err == nil { + newExif.GPSLatitude = &latitudeRaw + } + + sanitizeEXIF(newExif) + + return newExif, nil +} + +// isFloatReal returns true when the float value represents a real number +// (different than +Inf, -Inf or NaN) +func isFloatReal(v float64) bool { + if math.IsInf(v, 1) { + return false + } else if math.IsInf(v, -1) { + return false + } else if math.IsNaN(v) { + return false + } + return true +} + +// sanitizeEXIF removes any EXIF float64 field that is not a real number (+Inf, +// -Inf or Nan) +func sanitizeEXIF(exif *media.MediaEXIF) { + if exif.Exposure != nil && !isFloatReal(*exif.Exposure) { + exif.Exposure = nil + } + if exif.Aperture != nil && !isFloatReal(*exif.Aperture) { + exif.Aperture = nil + } + if exif.FocalLength != nil && !isFloatReal(*exif.FocalLength) { + exif.FocalLength = nil + } + if (exif.GPSLatitude != nil && !isFloatReal(*exif.GPSLatitude)) || + (exif.GPSLongitude != nil && !isFloatReal(*exif.GPSLongitude)) { + exif.GPSLatitude = nil + exif.GPSLongitude = nil + } +} |