-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexif.go
130 lines (111 loc) · 2.46 KB
/
exif.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// exif functions
//
package main
import (
"encoding/xml"
"errors"
"io"
"os"
"time"
"github.com/evanoberholster/imagemeta"
"github.com/evanoberholster/imagemeta/jpeg"
)
func getMetadata(file string) (time.Time, float64, float64, float64, error) {
// get lat, long, altitude, timestamp from jpgs
//
jpg, err := os.Open(file)
if err != nil {
return time.Time{}, 0.0, 0.0, 0.0, err
}
defer jpg.Close()
metadata, err := imagemeta.Decode(jpg)
if err != nil {
return time.Time{}, 0.0, 0.0, 0.0, err
}
timestamp := metadata.DateTimeOriginal()
lat := metadata.GPS.Latitude()
long := metadata.GPS.Longitude()
altitude := float64(metadata.GPS.Altitude())
if lat == 0.0 && long == 0.0 && altitude == 0 {
return timestamp, 0.0, 0.0, 0.0, errors.New("no GPS data")
}
return timestamp, lat, long, altitude, nil
}
type data struct {
Data string `xml:",chardata"`
}
type panoData struct {
Data string `xml:"ProjectionType,attr"`
}
// FIX THIS - is there a better way ?
var equirectangular bool
func is360(file string) bool {
equirectangular = false
// read xmp data to check if this is a 360 image
//
reader := func(r io.Reader) error {
d := xml.NewDecoder(r)
for {
tok, err := d.Token()
if tok == nil || err == io.EOF {
break
} else if err != nil {
return err
}
switch ty := tok.(type) {
case xml.StartElement:
if ty.Name.Local == "ProjectionType" {
var projectionType data
err = d.DecodeElement(&projectionType, &ty)
if err != nil {
return err
}
if projectionType.Data == "equirectangular" {
equirectangular = true
}
}
}
}
return nil
}
panoReader := func(r io.Reader) error {
println("pano start")
d := xml.NewDecoder(r)
for {
tok, err := d.Token()
if tok == nil || err == io.EOF {
break
} else if err != nil {
return err
}
switch ty := tok.(type) {
case xml.StartElement:
if ty.Name.Local == "Description" {
var projectionType panoData
err = d.DecodeElement(&projectionType, &ty)
if err != nil {
println("pano Description error " + err.Error())
return err
}
if projectionType.Data == "equirectangular" {
equirectangular = true
}
}
}
}
return nil
}
jpg, err := os.Open(file)
if err != nil {
return false
}
jpeg.ScanJPEG(jpg, nil, reader)
jpg.Close()
jpg, err = os.Open(file)
if err != nil {
return false
}
jpeg.ScanJPEG(jpg, nil, panoReader)
jpg.Close()
return equirectangular
}