mirror of
https://github.com/willnorris/imageproxy.git
synced 2026-04-24 20:36:24 +02:00
add support for exif orientation tag
if any transformation is requested, first apply any additional transformation necessary to correct for the EXIF orientation tag, since it is stripped from the resulting image. Fixes #63
This commit is contained in:
parent
07c54b46e3
commit
67619a67ae
2 changed files with 138 additions and 1 deletions
65
transform.go
65
transform.go
|
|
@ -21,9 +21,11 @@ import (
|
|||
_ "image/gif" // register gif format
|
||||
"image/jpeg"
|
||||
"image/png"
|
||||
"io"
|
||||
"math"
|
||||
|
||||
"github.com/disintegration/imaging"
|
||||
"github.com/rwcarlsen/goexif/exif"
|
||||
"golang.org/x/image/tiff" // register tiff format
|
||||
_ "golang.org/x/image/webp" // register webp format
|
||||
"willnorris.com/go/gifresize"
|
||||
|
|
@ -32,6 +34,9 @@ import (
|
|||
// default compression quality of resized jpegs
|
||||
const defaultQuality = 95
|
||||
|
||||
// maximum distance into image to look for EXIF tags
|
||||
const maxExifSize = 1 << 20
|
||||
|
||||
// resample filter used when resizing images
|
||||
var resampleFilter = imaging.Lanczos
|
||||
|
||||
|
|
@ -50,6 +55,15 @@ func Transform(img []byte, opt Options) ([]byte, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// apply EXIF orientation for jpeg and tiff source images. Read at most
|
||||
// up to maxExifSize looking for EXIF tags.
|
||||
if format == "jpeg" || format == "tiff" {
|
||||
r := io.LimitReader(bytes.NewReader(img), maxExifSize)
|
||||
if exifOpt := exifOrientation(r); exifOpt.transform() {
|
||||
m = transformImage(m, exifOpt)
|
||||
}
|
||||
}
|
||||
|
||||
// encode webp and tiff as jpeg by default
|
||||
if format == "tiff" || format == "webp" {
|
||||
format = "jpeg"
|
||||
|
|
@ -187,6 +201,57 @@ func cropParams(m image.Image, opt Options) (x0, y0, x1, y1 int, crop bool) {
|
|||
return x0, y0, x1, y1, true
|
||||
}
|
||||
|
||||
// read EXIF orientation tag from r and adjust opt to orient image correctly.
|
||||
func exifOrientation(r io.Reader) (opt Options) {
|
||||
// Exif Orientation Tag values
|
||||
// http://sylvana.net/jpegcrop/exif_orientation.html
|
||||
const (
|
||||
topLeftSide = 1
|
||||
topRightSide = 2
|
||||
bottomRightSide = 3
|
||||
bottomLeftSide = 4
|
||||
leftSideTop = 5
|
||||
rightSideTop = 6
|
||||
rightSideBottom = 7
|
||||
leftSideBottom = 8
|
||||
)
|
||||
|
||||
ex, err := exif.Decode(r)
|
||||
if err != nil {
|
||||
return opt
|
||||
}
|
||||
tag, err := ex.Get(exif.Orientation)
|
||||
if err != nil {
|
||||
return opt
|
||||
}
|
||||
orient, err := tag.Int(0)
|
||||
if err != nil {
|
||||
return opt
|
||||
}
|
||||
|
||||
switch orient {
|
||||
case topLeftSide:
|
||||
// do nothing
|
||||
case topRightSide:
|
||||
opt.FlipHorizontal = true
|
||||
case bottomRightSide:
|
||||
opt.Rotate = 180
|
||||
case bottomLeftSide:
|
||||
opt.FlipVertical = true
|
||||
case leftSideTop:
|
||||
opt.Rotate = 90
|
||||
opt.FlipVertical = true
|
||||
case rightSideTop:
|
||||
opt.Rotate = -90
|
||||
case rightSideBottom:
|
||||
opt.Rotate = 90
|
||||
opt.FlipHorizontal = true
|
||||
case leftSideBottom:
|
||||
opt.Rotate = 90
|
||||
}
|
||||
return opt
|
||||
}
|
||||
|
||||
// transformImage modifies the image m based on the transformations specified
|
||||
// in opt.
|
||||
func transformImage(m image.Image, opt Options) image.Image {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue