package photos import ( "bytes" "image" "time" "github.com/disintegration/imaging" "github.com/gen2brain/webp" "github.com/rwcarlsen/goexif/exif" ) type ImageMeta struct { Width int Height int MimeType string TakenAt *time.Time Latitude *float64 Longitude *float64 Thumb []byte Preview []byte } func inspect(data []byte) (width, height int, ok bool) { cfg, _, err := image.DecodeConfig(bytes.NewReader(data)) if err != nil { return 0, 0, false } return cfg.Width, cfg.Height, true } func extractEXIF(data []byte) (taken *time.Time, lat, lon *float64) { x, err := exif.Decode(bytes.NewReader(data)) if err != nil { return nil, nil, nil } if dt, err := x.Get(exif.DateTimeOriginal); err == nil { if s, err := dt.StringVal(); err == nil { if t, err := time.Parse("2006:01:02 15:04:05", s); err == nil { utc := t.UTC() taken = &utc } } } if la, lo, err := x.LatLong(); err == nil { lat, lon = &la, &lo } return taken, lat, lon } func buildVariants(data []byte) (thumb, preview []byte, err error) { img, err := imaging.Decode(bytes.NewReader(data), imaging.AutoOrientation(true)) if err != nil { return nil, nil, err } thumbImg := imaging.Fit(img, 200, 200, imaging.Lanczos) previewImg := imaging.Fit(img, 1200, 1200, imaging.Lanczos) opts := webp.Options{Quality: 82} var thumbBuf bytes.Buffer if err := webp.Encode(&thumbBuf, thumbImg, opts); err != nil { return nil, nil, err } var previewBuf bytes.Buffer if err := webp.Encode(&previewBuf, previewImg, opts); err != nil { return nil, nil, err } return thumbBuf.Bytes(), previewBuf.Bytes(), nil }