Skip to content

Instantly share code, notes, and snippets.

@slav123
Last active July 28, 2021 08:18
Show Gist options
  • Save slav123/ba2d4e8daf980c60347586c27aff52f5 to your computer and use it in GitHub Desktop.
Save slav123/ba2d4e8daf980c60347586c27aff52f5 to your computer and use it in GitHub Desktop.
package main
import (
exif "github.com/dsoprea/go-exif/v3"
exifcommon "github.com/dsoprea/go-exif/v3/common"
jpeg "github.com/dsoprea/go-jpeg-image-structure/v2"
)
func setExifTag(rootIB *exif.IfdBuilder, ifdPath, tagName, tagValue string) error {
fmt.Printf("setTag(): ifdPath: %v, tagName: %v, tagValue: %v",
ifdPath, tagName, tagValue)
ifdIb, err := exif.GetOrCreateIbFromRootIb(rootIB, ifdPath)
if err != nil {
return fmt.Errorf("Failed to get or create IB: %v", err)
}
if err := ifdIb.SetStandardWithName(tagName, tagValue); err != nil {
return fmt.Errorf("failed to set DateTime tag: %v", err)
}
return nil
}
func setDateIfNone(filepath string, t time.Time) error {
parser := jpeg.NewJpegMediaParser()
intfc, err := parser.ParseFile(filepath)
if err != nil {
return fmt.Errorf("Failed to parse JPEG file: %v", err)
}
sl := intfc.(*jpeg.SegmentList)
rootIb, err := sl.ConstructExifBuilder()
if err != nil {
fmt.Println("No EXIF; creating it from scratch")
im, err := exifcommon.NewIfdMappingWithStandard()
if err != nil {
return fmt.Errorf("Failed to create new IFD mapping with standard tags: %v", err)
}
ti := exif.NewTagIndex()
if err := exif.LoadStandardTags(ti); err != nil {
return fmt.Errorf("Failed to load standard tags: %v", err)
}
rootIb = exif.NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity,
exifcommon.EncodeDefaultByteOrder)
rootIb.AddStandardWithName("ProcessingSoftware", "photos-uploader")
}
//TODO check if DateTime is already set.
// Form our timestamp string
ts := exifcommon.ExifFullTimestampString(t)
// Set DateTime
ifdPath := "IFD0"
if err := setExifTag(rootIb, ifdPath, "DateTime", ts); err != nil {
return fmt.Errorf("Failed to set tag %v: %v", "DateTime", err)
}
// Set DateTimeOriginal
ifdPath = "IFD/Exif"
if err := setExifTag(rootIb, ifdPath, "DateTimeOriginal", ts); err != nil {
return fmt.Errorf("Failed to set tag %v: %v", "DateTimeOriginal", err)
}
// Update the exif segment.
if err := sl.SetExif(rootIb); err != nil {
return fmt.Errorf("Failed to set EXIF to jpeg: %v", err)
}
// Write the modified file
b := new(bytes.Buffer)
if err := sl.Write(b); err != nil {
return fmt.Errorf("Failed to create JPEG data: %v", err)
}
fmt.Printf("Number of image bytes: %v\n", len(b.Bytes()))
// Save the file
if err := ioutil.WriteFile(filepath, b.Bytes(), 0644); err != nil {
return fmt.Errorf("Failed to write JPEG file: %v", err)
}
fmt.Printf("Wrote %v\n", filepath)
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment