Merge pull request #258 from Kjeldgaard/244_exiftool
Use exiftool for parsing exif data
This commit is contained in:
commit
c0bced8c0a
|
@ -63,7 +63,7 @@ COPY api/data /app/data
|
|||
|
||||
RUN apt-get update \
|
||||
# Required dependencies
|
||||
&& apt-get install -y curl gpg libdlib19 ffmpeg libheif1
|
||||
&& apt-get install -y curl gpg libdlib19 ffmpeg exiftool libheif1
|
||||
|
||||
# Install Darktable if building for a supported architecture
|
||||
RUN if [ "${TARGETPLATFORM}" = "linux/amd64" ] || [ "${TARGETPLATFORM}" = "linux/arm64" ]; then \
|
||||
|
|
|
@ -5,6 +5,7 @@ go 1.16
|
|||
require (
|
||||
github.com/99designs/gqlgen v0.13.0
|
||||
github.com/Kagami/go-face v0.0.0-20200825065730-3dd2d74dccfb
|
||||
github.com/barasher/go-exiftool v1.4.0
|
||||
github.com/disintegration/imaging v1.6.2
|
||||
github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/gorilla/handlers v1.5.1
|
||||
|
|
|
@ -10,10 +10,13 @@ github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNg
|
|||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
|
||||
github.com/barasher/go-exiftool v1.4.0 h1:fTQsz1lWS15rRl13aFRjENt0gUXC+ZVBo/vICacn98A=
|
||||
github.com/barasher/go-exiftool v1.4.0/go.mod h1:F9s/a3uHSM8YniVfwF+sbQUtP8Gmh9nyzigNF+8vsWo=
|
||||
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
|
||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
@ -142,6 +145,7 @@ github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
|||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sabhiram/go-gitignore v0.0.0-20201211210132-54b8a0bf510f h1:8P2MkG70G76gnZBOPGwmMIgwBb/rESQuwsJ7K8ds4NE=
|
||||
github.com/sabhiram/go-gitignore v0.0.0-20201211210132-54b8a0bf510f/go.mod h1:+ePHsJ1keEjQtpvf9HHw0f4ZeJ0TLRsxhunSI2hYJSs=
|
||||
|
@ -152,6 +156,7 @@ github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9Nz
|
|||
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc h1:jUIKcSPO9MoMJBbEoyE/RJoE8vz7Mb8AjvifMMwSyvY=
|
||||
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
|
@ -170,6 +175,7 @@ github.com/strukturag/libheif v1.3.2 h1:NXft6czPSJiBeGc6hchNgczIY9aRPxsIcNIlVlDm
|
|||
github.com/strukturag/libheif v1.3.2/go.mod h1:E/PNRlmVtrtj9j2AvBZlrO4dsBDu6KfwDZn7X1Ce8Ks=
|
||||
github.com/strukturag/libheif v1.11.0 h1:HaWu5re98INSXNq7C8o5AwLcv2qD8+U7a+jVCpGWemI=
|
||||
github.com/strukturag/libheif v1.11.0/go.mod h1:E/PNRlmVtrtj9j2AvBZlrO4dsBDu6KfwDZn7X1Ce8Ks=
|
||||
github.com/urfave/cli/v2 v2.1.1 h1:Qt8FeAtxE/vfdrLmR3rxR6JRE0RoVmbXu8+6kZtYU4k=
|
||||
github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
|
||||
github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U=
|
||||
github.com/vektah/gqlparser/v2 v2.1.0 h1:uiKJ+T5HMGGQM2kRKQ8Pxw8+Zq9qhhZhz/lieYvCMns=
|
||||
|
@ -233,6 +239,7 @@ golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgw
|
|||
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589 h1:rjUrONFu4kLchcZTfp3/96bR8bW8dIa8uz3cR5n0cgM=
|
||||
golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
|
|
@ -1881,7 +1881,7 @@ type MediaEXIF {
|
|||
lens: String
|
||||
dateShot: Time
|
||||
"The exposure time of the image"
|
||||
exposure: String
|
||||
exposure: Float
|
||||
"The aperature stops of the image"
|
||||
aperture: Float
|
||||
"The ISO setting of the image"
|
||||
|
@ -1889,7 +1889,7 @@ type MediaEXIF {
|
|||
"The focal length of the lens, when the image was taken"
|
||||
focalLength: Float
|
||||
"A formatted description of the flash settings, when the image was taken"
|
||||
flash: String
|
||||
flash: Int
|
||||
"An index describing the mode for adjusting the exposure of the image"
|
||||
exposureProgram: Int
|
||||
}
|
||||
|
@ -4456,9 +4456,9 @@ func (ec *executionContext) _MediaEXIF_exposure(ctx context.Context, field graph
|
|||
if resTmp == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*string)
|
||||
res := resTmp.(*float64)
|
||||
fc.Result = res
|
||||
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
|
||||
return ec.marshalOFloat2ᚖfloat64(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _MediaEXIF_aperture(ctx context.Context, field graphql.CollectedField, obj *models.MediaEXIF) (ret graphql.Marshaler) {
|
||||
|
@ -4520,9 +4520,9 @@ func (ec *executionContext) _MediaEXIF_iso(ctx context.Context, field graphql.Co
|
|||
if resTmp == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*int)
|
||||
res := resTmp.(*int64)
|
||||
fc.Result = res
|
||||
return ec.marshalOInt2ᚖint(ctx, field.Selections, res)
|
||||
return ec.marshalOInt2ᚖint64(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _MediaEXIF_focalLength(ctx context.Context, field graphql.CollectedField, obj *models.MediaEXIF) (ret graphql.Marshaler) {
|
||||
|
@ -4584,9 +4584,9 @@ func (ec *executionContext) _MediaEXIF_flash(ctx context.Context, field graphql.
|
|||
if resTmp == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*string)
|
||||
res := resTmp.(*int64)
|
||||
fc.Result = res
|
||||
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
|
||||
return ec.marshalOInt2ᚖint64(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _MediaEXIF_exposureProgram(ctx context.Context, field graphql.CollectedField, obj *models.MediaEXIF) (ret graphql.Marshaler) {
|
||||
|
@ -4616,9 +4616,9 @@ func (ec *executionContext) _MediaEXIF_exposureProgram(ctx context.Context, fiel
|
|||
if resTmp == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*int)
|
||||
res := resTmp.(*int64)
|
||||
fc.Result = res
|
||||
return ec.marshalOInt2ᚖint(ctx, field.Selections, res)
|
||||
return ec.marshalOInt2ᚖint64(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _MediaURL_url(ctx context.Context, field graphql.CollectedField, obj *models.MediaURL) (ret graphql.Marshaler) {
|
||||
|
@ -11788,6 +11788,21 @@ func (ec *executionContext) marshalOInt2ᚖint(ctx context.Context, sel ast.Sele
|
|||
return graphql.MarshalInt(*v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalOInt2ᚖint64(ctx context.Context, v interface{}) (*int64, error) {
|
||||
if v == nil {
|
||||
return nil, nil
|
||||
}
|
||||
res, err := graphql.UnmarshalInt64(v)
|
||||
return &res, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalOInt2ᚖint64(ctx context.Context, sel ast.SelectionSet, v *int64) graphql.Marshaler {
|
||||
if v == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
return graphql.MarshalInt64(*v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalOMedia2ᚖgithubᚗcomᚋphotoviewᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐMedia(ctx context.Context, sel ast.SelectionSet, v *models.Media) graphql.Marshaler {
|
||||
if v == nil {
|
||||
return graphql.Null
|
||||
|
|
|
@ -10,13 +10,13 @@ type MediaEXIF struct {
|
|||
Maker *string
|
||||
Lens *string
|
||||
DateShot *time.Time
|
||||
Exposure *string
|
||||
Exposure *float64
|
||||
Aperture *float64
|
||||
Iso *int
|
||||
Iso *int64
|
||||
FocalLength *float64
|
||||
Flash *string
|
||||
Orientation *int
|
||||
ExposureProgram *int
|
||||
Flash *int64
|
||||
Orientation *int64
|
||||
ExposureProgram *int64
|
||||
GPSLatitude *float64
|
||||
GPSLongitude *float64
|
||||
}
|
||||
|
|
|
@ -304,7 +304,7 @@ type MediaEXIF {
|
|||
lens: String
|
||||
dateShot: Time
|
||||
"The exposure time of the image"
|
||||
exposure: String
|
||||
exposure: Float
|
||||
"The aperature stops of the image"
|
||||
aperture: Float
|
||||
"The ISO setting of the image"
|
||||
|
@ -312,7 +312,7 @@ type MediaEXIF {
|
|||
"The focal length of the lens, when the image was taken"
|
||||
focalLength: Float
|
||||
"A formatted description of the flash settings, when the image was taken"
|
||||
flash: String
|
||||
flash: Int
|
||||
"An index describing the mode for adjusting the exposure of the image"
|
||||
exposureProgram: Int
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/barasher/go-exiftool"
|
||||
"github.com/photoview/photoview/api/graphql/models"
|
||||
)
|
||||
|
||||
|
@ -31,7 +32,16 @@ func SaveEXIF(tx *gorm.DB, media *models.Media) (*models.MediaEXIF, error) {
|
|||
}
|
||||
}
|
||||
|
||||
var parser exifParser = &internalExifParser{}
|
||||
// Decide between internal or external Exif parser
|
||||
et, err := exiftool.NewExiftool()
|
||||
et.Close()
|
||||
var parser exifParser
|
||||
if err != nil {
|
||||
parser = &internalExifParser{}
|
||||
} else {
|
||||
parser = &externalExifParser{}
|
||||
}
|
||||
|
||||
|
||||
exif, err := parser.ParseExif(media)
|
||||
if err != nil {
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
package exif
|
||||
|
||||
import (
|
||||
"log"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/barasher/go-exiftool"
|
||||
"github.com/photoview/photoview/api/graphql/models"
|
||||
)
|
||||
|
||||
type externalExifParser struct{}
|
||||
|
||||
func (p *externalExifParser) ParseExif(media *models.Media) (returnExif *models.MediaEXIF, returnErr error) {
|
||||
// ExifTool - No print conversion mode
|
||||
et, err := exiftool.NewExiftool(exiftool.NoPrintConversion())
|
||||
if err != nil {
|
||||
log.Printf("Error initializing ExifTool: %s\n", err)
|
||||
return nil, err
|
||||
}
|
||||
defer et.Close()
|
||||
|
||||
fileInfos := et.ExtractMetadata(media.Path)
|
||||
newExif := models.MediaEXIF{}
|
||||
|
||||
for _, fileInfo := range fileInfos {
|
||||
if fileInfo.Err != nil {
|
||||
log.Printf("Fileinfo error\n")
|
||||
continue
|
||||
}
|
||||
|
||||
// Get camera model
|
||||
model, err := fileInfo.GetString("Model")
|
||||
if err == nil {
|
||||
log.Printf("Camera model: %v", model)
|
||||
newExif.Camera = &model
|
||||
}
|
||||
|
||||
// Get Camera make
|
||||
make, err := fileInfo.GetString("Make")
|
||||
if err == nil {
|
||||
log.Printf("Camera make: %v", make)
|
||||
newExif.Maker = &make
|
||||
}
|
||||
|
||||
// Get lens
|
||||
lens, err := fileInfo.GetString("LensModel")
|
||||
if err == nil {
|
||||
log.Printf("Lens: %v", lens)
|
||||
newExif.Lens = &lens
|
||||
}
|
||||
|
||||
//Get time of photo
|
||||
date, err := fileInfo.GetString("DateTimeOriginal")
|
||||
if err == nil {
|
||||
log.Printf("Date shot: %s", date)
|
||||
layout := "2006:01:02 15:04:05"
|
||||
dateTime, err := time.Parse(layout, date)
|
||||
if err == nil {
|
||||
newExif.DateShot = &dateTime
|
||||
}
|
||||
}
|
||||
|
||||
// Get exposure time
|
||||
exposureTime, err := fileInfo.GetFloat("ExposureTime")
|
||||
if err == nil {
|
||||
log.Printf("Exposure time: %f", exposureTime)
|
||||
newExif.Exposure = &exposureTime
|
||||
}
|
||||
|
||||
// Get aperture
|
||||
aperture, err := fileInfo.GetFloat("Aperture")
|
||||
if err == nil {
|
||||
log.Printf("Aperture: %f", aperture)
|
||||
newExif.Aperture = &aperture
|
||||
}
|
||||
|
||||
// Get ISO
|
||||
iso, err := fileInfo.GetInt("ISO")
|
||||
if err == nil {
|
||||
log.Printf("ISO: %d", iso)
|
||||
newExif.Iso = &iso
|
||||
}
|
||||
|
||||
// Get focal length
|
||||
focalLen, err := fileInfo.GetString("FocalLength")
|
||||
if err == nil {
|
||||
log.Printf("Focal length: %s", focalLen)
|
||||
reg, _ := regexp.Compile("[0-9.]+")
|
||||
focalLenStr := reg.FindString(focalLen)
|
||||
focalLenFloat, err := strconv.ParseFloat(focalLenStr, 64)
|
||||
if err == nil {
|
||||
newExif.FocalLength = &focalLenFloat
|
||||
}
|
||||
}
|
||||
|
||||
// Get flash info
|
||||
flash, err := fileInfo.GetInt("Flash")
|
||||
if err == nil {
|
||||
log.Printf("Flash: %d", flash)
|
||||
newExif.Flash = &flash
|
||||
}
|
||||
|
||||
// Get orientation
|
||||
orientation, err := fileInfo.GetInt("Orientation")
|
||||
if err == nil {
|
||||
log.Printf("Orientation: %d", orientation)
|
||||
newExif.Orientation = &orientation
|
||||
}
|
||||
|
||||
// Get exposure program
|
||||
expProgram, err := fileInfo.GetInt("ExposureProgram")
|
||||
if err == nil {
|
||||
log.Printf("Exposure Program: %d", expProgram)
|
||||
newExif.ExposureProgram = &expProgram
|
||||
}
|
||||
|
||||
// GPS coordinates - longitude
|
||||
longitudeRaw, err := fileInfo.GetFloat("GPSLongitude")
|
||||
if err == nil {
|
||||
log.Printf("GPS longitude: %f", longitudeRaw)
|
||||
newExif.GPSLongitude = &longitudeRaw
|
||||
}
|
||||
|
||||
// GPS coordinates - latitude
|
||||
latitudeRaw, err := fileInfo.GetFloat("GPSLatitude")
|
||||
if err == nil {
|
||||
log.Printf("GPS latitude: %f", latitudeRaw)
|
||||
newExif.GPSLatitude = &latitudeRaw
|
||||
}
|
||||
}
|
||||
|
||||
returnExif = &newExif
|
||||
return
|
||||
}
|
|
@ -58,10 +58,12 @@ func (p *internalExifParser) ParseExif(media *models.Media) (returnExif *models.
|
|||
newExif.DateShot = &date
|
||||
}
|
||||
|
||||
exposure, err := p.readRationalTag(exifTags, exif.ExposureTime, media)
|
||||
exposure, err := exifTags.Get(exif.ExposureTime)
|
||||
if err == nil {
|
||||
exposureStr := exposure.RatString()
|
||||
newExif.Exposure = &exposureStr
|
||||
exposureFloat, err := exposure.Float(0)
|
||||
if err == nil {
|
||||
newExif.Exposure = &exposureFloat
|
||||
}
|
||||
}
|
||||
|
||||
apertureRat, err := p.readRationalTag(exifTags, exif.FNumber, media)
|
||||
|
@ -78,7 +80,8 @@ func (p *internalExifParser) ParseExif(media *models.Media) (returnExif *models.
|
|||
if err != nil {
|
||||
log.Printf("WARN: Could not parse EXIF ISOSpeedRatings as integer: %s\n", media.Title)
|
||||
} else {
|
||||
newExif.Iso = &iso
|
||||
iso64 := int64(iso)
|
||||
newExif.Iso = &iso64
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,19 +108,22 @@ func (p *internalExifParser) ParseExif(media *models.Media) (returnExif *models.
|
|||
}
|
||||
}
|
||||
|
||||
flash, err := exifTags.Flash()
|
||||
flash, err := p.readIntegerTag(exifTags, exif.Flash, media)
|
||||
if err == nil {
|
||||
newExif.Flash = &flash
|
||||
flash64 := int64(*flash)
|
||||
newExif.Flash = &flash64
|
||||
}
|
||||
|
||||
orientation, err := p.readIntegerTag(exifTags, exif.Orientation, media)
|
||||
if err == nil {
|
||||
newExif.Orientation = orientation
|
||||
orientation64 := int64(*orientation)
|
||||
newExif.Orientation = &orientation64
|
||||
}
|
||||
|
||||
exposureProgram, err := p.readIntegerTag(exifTags, exif.ExposureProgram, media)
|
||||
if err == nil {
|
||||
newExif.ExposureProgram = exposureProgram
|
||||
exposureProgram64 := int64(*exposureProgram)
|
||||
newExif.ExposureProgram = &exposureProgram64
|
||||
}
|
||||
|
||||
lat, long, err := exifTags.LatLong()
|
||||
|
|
|
@ -134,6 +134,7 @@ const exifNameLookup = {
|
|||
flash: 'Flash',
|
||||
}
|
||||
|
||||
// From https://exiftool.org/TagNames/EXIF.html
|
||||
const exposurePrograms = {
|
||||
0: 'Not defined',
|
||||
1: 'Manual',
|
||||
|
@ -144,14 +145,58 @@ const exposurePrograms = {
|
|||
6: 'Action program',
|
||||
7: 'Portrait mode',
|
||||
8: 'Landscape mode ',
|
||||
9: 'Bulb',
|
||||
}
|
||||
|
||||
// From https://exiftool.org/TagNames/EXIF.html#Flash
|
||||
const flash = {
|
||||
0x0: 'No Flash',
|
||||
0x1: 'Fired',
|
||||
0x5: 'Fired, Return not detected',
|
||||
0x7: 'Fired, Return detected',
|
||||
0x8: 'On, Did not fire',
|
||||
0x9: 'On, Fired',
|
||||
0xd: 'On, Return not detected',
|
||||
0xf: 'On, Return detected',
|
||||
0x10: 'Off, Did not fire',
|
||||
0x14: 'Off, Did not fire, Return not detected',
|
||||
0x18: 'Auto, Did not fire',
|
||||
0x19: 'Auto, Fired',
|
||||
0x1d: 'Auto, Fired, Return not detected',
|
||||
0x1f: 'Auto, Fired, Return detected',
|
||||
0x20: 'No flash function',
|
||||
0x30: 'Off, No flash function',
|
||||
0x41: 'Fired, Red-eye reduction',
|
||||
0x45: 'Fired, Red-eye reduction, Return not detected',
|
||||
0x47: 'Fired, Red-eye reduction, Return detected',
|
||||
0x49: 'On, Red-eye reduction',
|
||||
0x4d: 'On, Red-eye reduction, Return not detected',
|
||||
0x4f: 'On, Red-eye reduction, Return detected',
|
||||
0x50: 'Off, Red-eye reduction',
|
||||
0x58: 'Auto, Did not fire, Red-eye reduction',
|
||||
0x59: 'Auto, Fired, Red-eye reduction',
|
||||
0x5d: 'Auto, Fired, Red-eye reduction, Return not detected',
|
||||
0x5f: 'Auto, Fired, Red-eye reduction, Return detected',
|
||||
}
|
||||
|
||||
// From https://exiftool.org/TagNames/EXIF.html
|
||||
// const orientation = {
|
||||
// 1: 'Horizontal (normal)',
|
||||
// 2: 'Mirror horizontal',
|
||||
// 3: 'Rotate 180',
|
||||
// 4: 'Mirror vertical',
|
||||
// 5: 'Mirror horizontal and rotate 270 CW',
|
||||
// 6: 'Rotate 90 CW',
|
||||
// 7: 'Mirror horizontal and rotate 90 CW',
|
||||
// 8: 'Rotate 270 CW',
|
||||
// }
|
||||
|
||||
const SidebarContent = ({ media, hidePreview }) => {
|
||||
let exifItems = []
|
||||
|
||||
if (media && media.exif) {
|
||||
let exifKeys = Object.keys(exifNameLookup).filter(
|
||||
x => !!media.exif[x] && x != '__typename'
|
||||
x => media.exif[x] !== undefined && x != '__typename'
|
||||
)
|
||||
|
||||
let exif = exifKeys.reduce(
|
||||
|
@ -163,18 +208,27 @@ const SidebarContent = ({ media, hidePreview }) => {
|
|||
)
|
||||
|
||||
exif.dateShot = new Date(exif.dateShot).toLocaleString()
|
||||
if (exif.exposureProgram) {
|
||||
|
||||
if (
|
||||
exif.exposureProgram !== undefined &&
|
||||
exif.exposureProgram !== 0 &&
|
||||
exposurePrograms[exif.exposureProgram]
|
||||
) {
|
||||
exif.exposureProgram = exposurePrograms[exif.exposureProgram]
|
||||
}
|
||||
|
||||
if (exif.aperture) {
|
||||
if (exif.aperture !== undefined) {
|
||||
exif.aperture = `f/${exif.aperture}`
|
||||
}
|
||||
|
||||
if (exif.focalLength) {
|
||||
if (exif.focalLength !== undefined) {
|
||||
exif.focalLength = `${exif.focalLength}mm`
|
||||
}
|
||||
|
||||
if (exif.flash !== undefined && flash[exif.flash]) {
|
||||
exif.flash = flash[exif.flash]
|
||||
}
|
||||
|
||||
exifItems = exifKeys.map(key => (
|
||||
<SidebarItem key={key} name={exifNameLookup[key]} value={exif[key]} />
|
||||
))
|
||||
|
|
Loading…
Reference in New Issue