Migrate to bimg & remove exif dependency

This commit is contained in:
2021-03-01 11:49:28 -05:00
parent 745d843af7
commit eba444459b
6 changed files with 100 additions and 133 deletions

View File

@@ -4,12 +4,13 @@ import (
"context"
"errors"
"net/http"
"strconv"
"strings"
"time"
"github.com/dsoprea/go-exif/v3"
exifcommon "github.com/dsoprea/go-exif/v3/common"
"github.com/google/uuid"
"github.com/h2non/bimg"
log "github.com/sirupsen/logrus"
"reichard.io/imagini/graph/model"
)
@@ -76,50 +77,50 @@ func deriveDeviceType(r *http.Request) model.DeviceType {
return model.DeviceTypeUnknown
}
func mediaItemFromEXIFData(filePath string) (*model.MediaItem, error) {
rawExif, err := exif.SearchFileAndExtractExif(filePath)
entries, _, err := exif.GetFlatExifData(rawExif, nil)
decLong := float64(1)
decLat := float64(1)
func mediaItemFromEXIF(meta bimg.EXIF) *model.MediaItem {
mediaItem := &model.MediaItem{}
for _, v := range entries {
if v.TagName == "DateTimeOriginal" {
formattedTime, _ := time.Parse("2006:01:02 15:04:05", v.Formatted)
mediaItem.ExifDate = &formattedTime
} else if v.TagName == "GPSLatitude" {
latStruct := v.Value.([]exifcommon.Rational)
decLat *= deriveDecimalCoordinate(
latStruct[0].Numerator/latStruct[0].Denominator,
latStruct[1].Numerator/latStruct[1].Denominator,
float64(latStruct[2].Numerator)/float64(latStruct[2].Denominator),
)
} else if v.TagName == "GPSLongitude" {
longStruct := v.Value.([]exifcommon.Rational)
decLong *= deriveDecimalCoordinate(
longStruct[0].Numerator/longStruct[0].Denominator,
longStruct[1].Numerator/longStruct[1].Denominator,
float64(longStruct[2].Numerator)/float64(longStruct[2].Denominator),
)
} else if v.TagName == "GPSLatitudeRef" && v.Formatted == "S" {
decLat *= -1
} else if v.TagName == "GPSLongitudeRef" && v.Formatted == "W" {
decLong *= -1
// DateTimeOriginal
formattedTime, _ := time.Parse("2006:01:02 15:04:05", meta.DateTimeOriginal)
mediaItem.ExifDate = &formattedTime
// GPSLatitude / Ref
mediaItem.Latitude = deriveDecimalCoordinate(meta.GPSLatitude, meta.GPSLatitudeRef)
// GPSLongitude / Ref
mediaItem.Longitude = deriveDecimalCoordinate(meta.GPSLongitude, meta.GPSLongitudeRef)
return mediaItem
}
func deriveDecimalCoordinate(coords, direction string) *float64 {
divideBy := [3]float64{1, 60, 3600}
var calculatedResult float64
splitCoords := strings.Split(coords, " ")
if len(splitCoords) != 3 {
return nil
}
for i := 0; i < len(splitCoords); i++ {
splitSection := strings.Split(splitCoords[i], "/")
numerator, err := strconv.ParseFloat(splitSection[0], 64)
if err != nil {
return nil
}
denominator, err := strconv.ParseFloat(splitSection[1], 64)
if err != nil {
return nil
}
calculatedResult += numerator / denominator / divideBy[i]
}
mediaItem.Latitude = &decLat
mediaItem.Longitude = &decLong
// Gross
if err != nil && err.Error() == "no exif data" {
return mediaItem, nil
if direction == "S" {
calculatedResult *= -1
} else if direction == "W" {
calculatedResult *= -1
}
return mediaItem, err
}
func deriveDecimalCoordinate(degrees, minutes uint32, seconds float64) float64 {
return float64(degrees) + (float64(minutes) / 60) + (seconds / 3600)
log.Info(calculatedResult)
return &calculatedResult
}

View File

@@ -8,15 +8,16 @@ import (
"context"
"errors"
"io"
"io/ioutil"
"net/http"
"os"
"path"
"strings"
"time"
"github.com/davidbyttow/govips/v2/vips"
"github.com/gabriel-vasile/mimetype"
"github.com/google/uuid"
"github.com/h2non/bimg"
log "github.com/sirupsen/logrus"
"reichard.io/imagini/graph/generated"
"reichard.io/imagini/graph/model"
@@ -79,25 +80,36 @@ func (r *mutationResolver) CreateMediaItem(ctx context.Context, input model.NewM
return nil, errors.New("Upload Failed")
}
// Create MediaItem From EXIF Data
mediaItem, err := mediaItemFromEXIFData(filePath)
// Load Image
f.Seek(0, io.SeekStart)
buffer, err := ioutil.ReadAll(f)
newImage := bimg.NewImage(buffer)
// Create MediaItem from EXIF
meta, err := newImage.Metadata()
if err != nil {
log.Error("[upload] Unable to extract EXIF data:", err)
log.Error("[upload] Unable to extract metadata:", err)
return nil, errors.New("Upload Failed")
}
mediaItem := mediaItemFromEXIF(meta.EXIF)
// Use Vips for Width & Height
f.Seek(0, io.SeekStart)
image, err := vips.NewImageFromReader(f)
// Determine Image Size
imageSize, err := newImage.Size()
if err != nil {
log.Error("[upload] Unable to extract dimension data:", err)
return nil, errors.New("Upload Failed")
}
if meta.Orientation > 4 {
mediaItem.Width = imageSize.Height
mediaItem.Height = imageSize.Width
} else {
mediaItem.Width = imageSize.Width
mediaItem.Height = imageSize.Height
}
// Add Additional MediaItem Fields
mediaItem.ID = mediaItemID
mediaItem.Width = image.Width()
mediaItem.Height = image.Height()
mediaItem.UserID = userID
mediaItem.IsVideo = isVideo
mediaItem.FileName = fileName