I'm writing a go application that uses gqlgen
for graphQL API.
when a user uploads a file using the api I get it as a type of graphql.Upload
type Upload struct {
File io.Reader
Filename string
Size int64
ContentType string
}
I want to be able to load the exif data of the image, decode the image and rotate it based on the exif orientation.
I use github.com/rwcarlsen/goexif/exif
to fetch the exif information and github.com/disintegration/imaging
for rotation, but I cannot open graphql.Upload.File
twice. it fails the 2hd time.
func updateImage(dir string, id int, imgFile *graphql.Upload) error {
image := dbimage.GetImagePathNoTemplate(dir, id)
imageThumbnail := dbimage.GetImageThumbnailPathNoTemplate(dir, id)
var myImage image2.Image
var err error
switch imgFile.ContentType {
case "image/png":
if myImage, err = png.Decode(imgFile.File); err != nil {
return err
}
break
case "image/jpeg":
if myImage, err = jpeg.Decode(imgFile.File); err != nil {
return err
}
break
case "image/webp":
if myImage, err = webpbin.Decode(imgFile.File); err != nil {
return err
}
break
default:
return errors.Errorf("unknown image mimetype %v", imgFile.ContentType)
}
FAILS HERE: metaData, err := exif.Decode(imgFile.File)
...
}
of course if I extract the exif first and then decode the image, then the image decode fails.
I don't get a full path to the file and I get only one io.Reader
. what can I do to fetch both exif and decode the image ?
thanks
guys thank you for your comments.
I noticed that I cannot cast io.Reader
to io.Seeker
.
for some reason I thought that io.Reader
got some sort of rewind method that I missed but this is not the case.
so what I did is read the data to a byte array and created new Reader object whenever I need it:
byteArray, err := ioutil.ReadAll(imgFile.File)
if err != nil {
return err
}
switch imgFile.ContentType {
case "image/png":
if myImage, err = png.Decode(bytes.NewReader(byteArray)); err != nil {
return err
}
break
case "image/jpeg":
if myImage, err = jpeg.Decode(bytes.NewReader(byteArray)); err != nil {
return err
}
break
case "image/webp":
if myImage, err = webpbin.Decode(bytes.NewReader(byteArray)); err != nil {
return err
}
break
default:
return errors.Errorf("unknown image mimetype %v", imgFile.ContentType)
}
metaData, err := exif.Decode(bytes.NewReader(byteArray))