2020-01-07 17:36:49 +01:00
|
|
|
package meta
|
|
|
|
|
|
|
|
import (
|
2020-05-14 11:57:26 +02:00
|
|
|
"math"
|
2020-01-07 17:36:49 +01:00
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2020-01-07 18:13:53 +01:00
|
|
|
// Data represents image meta data.
|
2020-01-07 17:36:49 +01:00
|
|
|
type Data struct {
|
2020-05-27 13:40:21 +02:00
|
|
|
DocumentID string `meta:"ImageUniqueID,OriginalDocumentID,DocumentID"`
|
|
|
|
InstanceID string `meta:"InstanceID,DocumentID"`
|
2020-05-16 09:27:21 +02:00
|
|
|
TakenAt time.Time `meta:"DateTimeOriginal,CreateDate,MediaCreateDate,DateTimeDigitized,DateTime"`
|
|
|
|
TakenAtLocal time.Time `meta:"DateTimeOriginal,CreateDate,MediaCreateDate,DateTimeDigitized,DateTime"`
|
2020-05-13 21:22:49 +02:00
|
|
|
TimeZone string `meta:"-"`
|
2020-05-15 09:39:32 +02:00
|
|
|
Duration time.Duration `meta:"Duration,MediaDuration,TrackDuration"`
|
2020-05-27 13:40:21 +02:00
|
|
|
Codec string `meta:"CompressorID,Compression,FileType"`
|
2020-05-13 21:22:49 +02:00
|
|
|
Title string `meta:"Title"`
|
2020-06-27 14:15:25 +02:00
|
|
|
Subject string `meta:"Subject,PersonInImage,ObjectName"`
|
2020-05-13 21:22:49 +02:00
|
|
|
Keywords string `meta:"Keywords"`
|
|
|
|
Comment string `meta:"-"`
|
|
|
|
Artist string `meta:"Artist,Creator"`
|
|
|
|
Description string `meta:"Description"`
|
|
|
|
Copyright string `meta:"Rights,Copyright"`
|
|
|
|
CameraMake string `meta:"CameraMake,Make"`
|
|
|
|
CameraModel string `meta:"CameraModel,Model"`
|
|
|
|
CameraOwner string `meta:"OwnerName"`
|
|
|
|
CameraSerial string `meta:"SerialNumber"`
|
|
|
|
LensMake string `meta:"LensMake"`
|
|
|
|
LensModel string `meta:"Lens,LensModel"`
|
|
|
|
Flash bool `meta:"-"`
|
|
|
|
FocalLength int `meta:"-"`
|
|
|
|
Exposure string `meta:"ExposureTime"`
|
|
|
|
Aperture float32 `meta:"ApertureValue"`
|
|
|
|
FNumber float32 `meta:"FNumber"`
|
|
|
|
Iso int `meta:"ISO"`
|
|
|
|
GPSPosition string `meta:"GPSPosition"`
|
2020-05-14 11:57:26 +02:00
|
|
|
GPSLatitude string `meta:"GPSLatitude"`
|
|
|
|
GPSLongitude string `meta:"GPSLongitude"`
|
|
|
|
Lat float32 `meta:"-"`
|
|
|
|
Lng float32 `meta:"-"`
|
|
|
|
Altitude int `meta:"GlobalAltitude"`
|
2020-05-18 17:38:14 +02:00
|
|
|
Width int `meta:"PixelXDimension,ImageWidth,ExifImageWidth,SourceImageWidth"`
|
|
|
|
Height int `meta:"PixelYDimension,ImageHeight,ImageLength,ExifImageHeight,SourceImageHeight"`
|
2020-05-13 21:22:49 +02:00
|
|
|
Orientation int `meta:"-"`
|
2020-05-14 14:28:23 +02:00
|
|
|
Rotation int `meta:"Rotation"`
|
2020-05-27 13:40:21 +02:00
|
|
|
Error error `meta:"-"`
|
2020-05-13 21:22:49 +02:00
|
|
|
All map[string]string
|
2020-01-07 17:36:49 +01:00
|
|
|
}
|
2020-05-14 11:57:26 +02:00
|
|
|
|
|
|
|
// AspectRatio returns the aspect ratio based on width and height.
|
|
|
|
func (data Data) AspectRatio() float32 {
|
2020-06-04 14:56:27 +02:00
|
|
|
width := float64(data.ActualWidth())
|
|
|
|
height := float64(data.ActualHeight())
|
2020-05-14 11:57:26 +02:00
|
|
|
|
|
|
|
if width <= 0 || height <= 0 {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
aspectRatio := float32(width / height)
|
|
|
|
|
|
|
|
return aspectRatio
|
|
|
|
}
|
|
|
|
|
|
|
|
// Portrait returns true if it's a portrait picture or video based on width and height.
|
|
|
|
func (data Data) Portrait() bool {
|
|
|
|
return data.Width < data.Height
|
|
|
|
}
|
|
|
|
|
|
|
|
// Megapixels returns the resolution in megapixels.
|
|
|
|
func (data Data) Megapixels() int {
|
|
|
|
return int(math.Round(float64(data.Width*data.Height) / 1000000))
|
|
|
|
}
|
2020-05-27 13:40:21 +02:00
|
|
|
|
|
|
|
// HasDocumentID returns true if a DocumentID exists.
|
|
|
|
func (data Data) HasDocumentID() bool {
|
|
|
|
return len(data.DocumentID) >= 15
|
|
|
|
}
|
|
|
|
|
|
|
|
// HasInstanceID returns true if an InstanceID exists.
|
|
|
|
func (data Data) HasInstanceID() bool {
|
|
|
|
return len(data.InstanceID) >= 15
|
|
|
|
}
|
|
|
|
|
|
|
|
// HasTimeAndPlace if data contains a time and gps position.
|
|
|
|
func (data Data) HasTimeAndPlace() bool {
|
|
|
|
return !data.TakenAt.IsZero() && data.Lat != 0 && data.Lng != 0
|
|
|
|
}
|
2020-06-04 14:56:27 +02:00
|
|
|
|
|
|
|
// ActualWidth is the width after rotating the media file if needed.
|
|
|
|
func (data Data) ActualWidth() int {
|
|
|
|
if data.Orientation > 4 {
|
|
|
|
return data.Height
|
|
|
|
}
|
|
|
|
|
|
|
|
return data.Width
|
|
|
|
}
|
|
|
|
|
|
|
|
// ActualHeight is the height after rotating the media file if needed.
|
|
|
|
func (data Data) ActualHeight() int {
|
|
|
|
if data.Orientation > 4 {
|
|
|
|
return data.Width
|
|
|
|
}
|
|
|
|
|
|
|
|
return data.Height
|
|
|
|
}
|