Skip to content

Commit e603bc3

Browse files
author
thisisaaronland
committed
Update docs
1 parent 24db671 commit e603bc3

File tree

4 files changed

+151
-34
lines changed

4 files changed

+151
-34
lines changed

README.md

Lines changed: 131 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,16 @@ The blog post [Updating EXIF metadata in JavaScript (and WebAssembly)](https://m
88

99
## Important
1010

11-
As of this writing the majority of EXIF tags are _not_ supported. Currently only EXIF tags of types `ASCII` and `BYTE` are supported. This is not ideal but I am still trying to get familiar with the requirements of the `go-exif` package. Contributions and patches for the other remaining EXIF tag types is welcomed.
11+
As of this writing the majority of EXIF tags are _not_ supported. Currently only EXIF tags of with the following EXIF types are supported: `ASCII`, `BYTE`, `RATIONAL` and `SRATIONAL` are supported. This is not ideal but I am still trying to get familiar with the requirements of the `go-exif` package. Contributions and patches for the other remaining EXIF tag types is welcomed.
1212

1313
## Documentation
1414

1515
[![Go Reference](https://pkg.go.dev/badge/github.com/sfomuseum/go-exif-update.svg)](https://pkg.go.dev/github.com/sfomuseum/go-exif-update)
1616

1717
### Example
1818

19+
_Error handling removed for the sake of brevity._
20+
1921
```
2022
package main
2123
@@ -41,10 +43,36 @@ func main() {
4143
update.UpdateExif(fh, os.Stdout, exif_props)
4244
}
4345
}
46+
```
47+
48+
The properties passed to the [UpdateExif](https://pkg.go.dev/github.com/sfomuseum/go-exif-update#UpdateExif) method are assumed to be suitably typed to be used as input for the [exif.SetStandardWithName](https://pkg.go.dev/github.com/dsoprea/go-exif/v3#IfdBuilder.SetStandardWithName) method. For anything other than simple strings this can become a fairly involved process. I am still trying the understand the `go-exif` documentation and requirements so any guidance I have to offer remains limited.
49+
50+
This package also provides a convenience [PrepareAndUpdateExif](https://pkg.go.dev/github.com/sfomuseum/go-exif-update#PrepareUpdateExif) method which attempts to translate EXIF property values in to their corresponding `go-exif` type before invoking the `UpdateExif` method. For example:
4451

4552
```
53+
exif_props := map[string]interface{}{
54+
"FNumber": "11/1", // FNumber is stored as a `RATIONAL` value rather than as a string (or `ASCI`)
55+
}
56+
57+
for _, path := range paths {
4658
47-
_Error handling removed for the sake of brevity._
59+
fh, _ := os.Open(path)
60+
defer fh.Close()
61+
62+
update.PrepareAndUpdateExif(fh, os.Stdout, exif_props)
63+
}
64+
```
65+
66+
### Non-standard tags
67+
68+
The `PrepareAndUpdateExif` method also supports a limited set of custom non-standard tags. These are provided to simplify the process of assigning multiple or complex EXIF tags.
69+
70+
The list of currently supported non-standard tags is:
71+
72+
| Name | Value | Description | Notes |
73+
| --- | --- | --- | --- |
74+
| `X-Latitude` | float64 | Assign a decimal latitude value in to its corresponding `GPSLatitude` and `GPSLatitudeRef` properties. | |
75+
| `X-Longitude` | float64 | Assign a decimal longitude value in to its corresponding `GPSLongitude` and `GPSLongitudeRef` properties. | |
4876

4977
## Tools
5078

@@ -86,6 +114,8 @@ Copyright true
86114
ImageWidth false
87115
```
88116

117+
_As of this writing non-standard tags, described above, are not considered when processing tags._
118+
89119
### tags-supported
90120

91121
Command-line tool that prints a list of EXIF tag names, sorted alphabetically, that are supported by the sfomuseum/go-exif-update package.
@@ -98,6 +128,8 @@ Usage:
98128
./bin/tags-supported
99129
```
100130

131+
_As of this writing non-standard tags, described above, are not considered when listing supported tags._
132+
101133
### update-exif
102134

103135
Command-line tool for updating the EXIF properties in one or more JPEG images.
@@ -130,6 +162,26 @@ Exif.Image.Artist Ascii 4 Bob
130162
Exif.Image.Copyright Ascii 6 Alice
131163
```
132164

165+
This tool uses the `PrepareAndUpdateExif` method and supports non-standard tags, both described above. For example:
166+
167+
```
168+
$> ./bin/update-exif \
169+
-property X-Latitude=37.61799 \
170+
-property X-Longitude=-122.384864 \
171+
-property Artist=Walrus \
172+
fixtures/walrus.jpg \
173+
174+
> walrus-exif.jpg
175+
176+
$> exiv2 -pa walrus-exif.jpg
177+
Exif.Image.GPSTag Long 1 45
178+
Exif.GPSInfo.GPSLongitude Rational 3 122deg 23' 5"
179+
Exif.GPSInfo.GPSLongitudeRef Ascii 2 West
180+
Exif.GPSInfo.GPSLatitude Rational 3 37deg 37' 4"
181+
Exif.GPSInfo.GPSLatitudeRef Ascii 2 North
182+
Exif.Image.Artist Ascii 7 Walrus
183+
```
184+
133185
### update-exif-wasm-demo
134186

135187
HTTP server for demonstrating the use of the update_exif WebAssembly binary.
@@ -197,44 +249,102 @@ An abbreviated version of the code to use the `update_exif.wasm` binary in JavaS
197249

198250
For a complete example consult the [www/javascript/index.js](www/javascript/index.js) file.
199251

252+
The WASM binary included with tool uses the `PrepareAndUpdateExif` method and supports non-standard tags, both described above.
253+
200254
## Supported tags
201255

202256
The following EXIF tags are supported by this package. This list was generated by the `tags-supported` tool.
203257

204258
```
259+
AnalogBalance
260+
AntiAliasStrength
261+
ApertureValue
262+
ApertureValue
205263
Artist
264+
AsShotPreProfileMatrix
206265
AsShotProfileName
266+
AsShotWhiteXY
267+
BaselineExposure
268+
BaselineNoise
269+
BaselineSharpness
270+
BatteryLevel
271+
BestQualityScale
272+
BlackLevel
273+
BlackLevelDeltaH
274+
BlackLevelDeltaV
207275
BodySerialNumber
276+
BrightnessValue
277+
BrightnessValue
208278
CFAPattern
209279
CFAPlaneColor
280+
CameraCalibration1
281+
CameraCalibration2
210282
CameraCalibrationSignature
211283
CameraOwnerName
212284
CameraSerialNumber
285+
ChromaBlurRadius
213286
ClipPath
287+
ColorMatrix1
288+
ColorMatrix2
289+
CompressedBitsPerPixel
290+
CompressedBitsPerPixel
214291
Copyright
292+
CurrentPreProfileMatrix
215293
DNGBackwardVersion
216294
DNGPrivateData
217295
DNGVersion
218296
DateTime
219297
DateTimeDigitized
220298
DateTimeOriginal
221299
DateTimeOriginal
300+
DefaultScale
301+
DigitalZoomRatio
222302
DocumentName
223303
DotRange
304+
ExposureBiasValue
305+
ExposureBiasValue
306+
ExposureIndex
307+
ExposureIndex
308+
ExposureTime
309+
ExposureTime
310+
FNumber
311+
FNumber
312+
FlashEnergy
313+
FlashEnergy
314+
FocalLength
315+
FocalLength
316+
FocalPlaneXResolution
317+
FocalPlaneXResolution
318+
FocalPlaneYResolution
319+
FocalPlaneYResolution
320+
ForwardMatrix1
321+
ForwardMatrix2
322+
GPSAltitude
224323
GPSAltitudeRef
324+
GPSDOP
225325
GPSDateStamp
326+
GPSDestBearing
226327
GPSDestBearingRef
328+
GPSDestDistance
227329
GPSDestDistanceRef
330+
GPSDestLatitude
228331
GPSDestLatitudeRef
332+
GPSDestLongitude
229333
GPSDestLongitudeRef
334+
GPSImgDirection
230335
GPSImgDirectionRef
336+
GPSLatitude
231337
GPSLatitudeRef
338+
GPSLongitude
232339
GPSLongitudeRef
233340
GPSMapDatum
234341
GPSMeasureMode
235342
GPSSatellites
343+
GPSSpeed
236344
GPSSpeedRef
237345
GPSStatus
346+
GPSTimeStamp
347+
GPSTrack
238348
GPSTrackRef
239349
GPSVersionID
240350
HostComputer
@@ -245,19 +355,26 @@ ImageResources
245355
ImageUniqueID
246356
InkNames
247357
InteroperabilityIndex
358+
LensInfo
248359
LensMake
249360
LensModel
250361
LensSerialNumber
362+
LensSpecification
363+
LinearResponseLimit
251364
LocalizedCameraModel
252365
Make
366+
MaxApertureValue
367+
MaxApertureValue
253368
Model
254369
NoiseProfile
370+
NoiseReductionApplied
255371
OriginalRawFileName
256372
PreviewApplicationName
257373
PreviewApplicationVersion
258374
PreviewDateTime
259375
PreviewSettingsDigest
260376
PreviewSettingsName
377+
PrimaryChromaticities
261378
ProcessingSoftware
262379
ProfileCalibrationSignature
263380
ProfileCopyright
@@ -267,27 +384,39 @@ ProfileLookTableData
267384
ProfileName
268385
ProfileToneCurve
269386
RawDataUniqueID
387+
ReductionMatrix1
388+
ReductionMatrix2
389+
ReferenceBlackWhite
270390
RelatedImageFileFormat
271391
RelatedSoundFile
272392
SecurityClassification
393+
ShadowScale
394+
ShutterSpeedValue
395+
ShutterSpeedValue
273396
Software
274397
SpectralSensitivity
275398
SpectralSensitivity
276399
SubSecTime
277400
SubSecTimeDigitized
278401
SubSecTimeOriginal
402+
SubjectDistance
403+
SubjectDistance
279404
TIFFEPStandardID
280405
TargetPrinter
281406
TimeZoneOffset
282407
UniqueCameraModel
408+
WhitePoint
283409
XClipPathUnits
284410
XMLPacket
285411
XPAuthor
286412
XPComment
287413
XPKeywords
288414
XPSubject
289415
XPTitle
416+
XResolution
417+
YCbCrCoefficients
290418
YClipPathUnits
419+
YResolution
291420
```
292421

293422
## See also

cmd/tags-supported-wasm/main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ func main() {
2020
log.Printf("Failed to derive supported tags, %v", err)
2121
return nil
2222
}
23-
23+
2424
sort.Strings(tags_supported)
2525

2626
x_tags := []string{
@@ -31,7 +31,7 @@ func main() {
3131
for _, t := range x_tags {
3232
tags_supported = append(tags_supported, t)
3333
}
34-
34+
3535
enc_supported, err := json.Marshal(tags_supported)
3636

3737
if err != nil {

cmd/update-exif/main.go

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@ func main() {
1616
var properties multi.KeyValueString
1717
flag.Var(&properties, "property", "One or more {TAG}={VALUE} EXIF properties. {TAG} must be a recognized EXIF tag.")
1818

19-
lat := flag.Float64("latitude", 0.0, "")
20-
lon := flag.Float64("longitude", 0.0, "")
21-
2219
flag.Usage = func() {
2320
fmt.Fprintf(os.Stderr, "Command-line tool for updating the EXIF properties in one or more JPEG images. Images are not updated in place but written to STDOUT.\n\n")
2421
fmt.Fprintf(os.Stderr, "Usage:\n\t%s [options] image(N) image(N) image(N)\n\n", os.Args[0])
@@ -52,15 +49,6 @@ func main() {
5249
exif_props[k] = v
5350
}
5451

55-
if *lat != 0.0 && *lon != 0.0 {
56-
57-
err := update.AppendGPSPropertiesWithLatitudeAndLongitude(exif_props, *lat, *lon)
58-
59-
if err != nil {
60-
log.Fatalf("Failed to append latitude and longitude properties, %v", err)
61-
}
62-
}
63-
6452
for _, path := range paths {
6553

6654
fh, err := os.Open(path)

update.go

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,24 @@ func UpdateExif(r io.Reader, wr io.Writer, exif_props map[string]interface{}) er
179179
return sl.Write(wr)
180180
}
181181

182+
// Return the *exifcommon.IfdIdentity and *exif.IndexedTag instances associated
183+
// with a given EXIF string tag name.
184+
func GetIndexedTagFromName(k string) (*exifcommon.IfdIdentity, *exif.IndexedTag, error) {
185+
186+
for _, id := range tag_paths {
187+
188+
t, err := ti.GetWithName(id, k)
189+
190+
if err != nil {
191+
continue
192+
}
193+
194+
return id, t, nil
195+
}
196+
197+
return nil, nil, fmt.Errorf("Unrecognized tag, %s", k)
198+
}
199+
182200
// Cribbed from https://github.com/dsoprea/go-exif/issues/11
183201

184202
func setExifTag(rootIB *exif.IfdBuilder, ifdPath string, tagName string, tagValue interface{}) error {
@@ -199,21 +217,3 @@ func setExifTag(rootIB *exif.IfdBuilder, ifdPath string, tagName string, tagValu
199217

200218
return nil
201219
}
202-
203-
// Return the *exifcommon.IfdIdentity and *exif.IndexedTag instances associated
204-
// with a given EXIF string tag name.
205-
func GetIndexedTagFromName(k string) (*exifcommon.IfdIdentity, *exif.IndexedTag, error) {
206-
207-
for _, id := range tag_paths {
208-
209-
t, err := ti.GetWithName(id, k)
210-
211-
if err != nil {
212-
continue
213-
}
214-
215-
return id, t, nil
216-
}
217-
218-
return nil, nil, fmt.Errorf("Unrecognized tag, %s", k)
219-
}

0 commit comments

Comments
 (0)