github.com/go-oss/image@v0.1.1-0.20230517025328-001b78555e78/imageutil/decode.go (about) 1 // Package imageutil wrapper for jpeg.DecodeWithQuality & remove exif, apply orientation. 2 package imageutil 3 4 import ( 5 "bytes" 6 "errors" 7 "image" 8 "io" 9 10 jq "github.com/go-oss/image/jpeg" 11 "github.com/rwcarlsen/goexif/exif" 12 13 // use webp decoder 14 _ "golang.org/x/image/webp" 15 ) 16 17 var ( 18 // ErrUnsupportedFileType represents unsupported error. 19 ErrUnsupportedFileType = errors.New("unsupported file type") 20 ) 21 22 // Image represents image.Image wrapper. 23 type Image struct { 24 Image image.Image 25 Quality int 26 OriginalMIMEType MIMEType 27 } 28 29 // Decode image file. 30 func Decode(file io.Reader) (*Image, error) { 31 fileHeader := make([]byte, 512) 32 _, err := file.Read(fileHeader) 33 if err != nil { 34 return nil, err 35 } 36 37 multiReader := io.MultiReader(bytes.NewBuffer(fileHeader), file) 38 39 mimeType := DetectMimeType(fileHeader) 40 if mimeType == UndefinedType { 41 return nil, ErrUnsupportedFileType 42 } 43 44 buff := new(bytes.Buffer) 45 reader := io.TeeReader(multiReader, buff) 46 47 img := &Image{ 48 OriginalMIMEType: mimeType, 49 } 50 51 if mimeType == JPEG { 52 img.Image, img.Quality, err = jq.DecodeWithQuality(reader) 53 if err != nil { 54 return nil, err 55 } 56 57 // check EXIF and apply orientation 58 meta, decodeErr := exif.Decode(buff) 59 // if error occurred, exif is invalid and discarded. 60 if decodeErr == nil { 61 newImg, _ := applyOrientation(img.Image, meta) 62 if newImg != nil { 63 img.Image = newImg 64 } 65 } 66 } else { 67 img.Image, _, err = image.Decode(reader) 68 if err != nil { 69 return nil, err 70 } 71 } 72 73 return img, nil 74 }