package logic import ( "github.com/dubbogo/gost/log/logger" "github.com/rwcarlsen/goexif/exif" "golang.org/x/image/bmp" "image" "image/jpeg" "image/png" "os" "path" "strings" ) // ReadOrientation 方向判断 func ReadOrientation(filename string) (direct int, err error) { file, err := os.Open(filename) defer file.Close() if err != nil { logger.Error("failed to open file, err: ", err) return } x, err := exif.Decode(file) if err != nil { logger.Error("failed to decode file, err: ", err) return } orientation, err := x.Get(exif.Orientation) if err != nil { logger.Error("failed to orientation file, err: ", err) return } direct, err = orientation.Int(0) if err != nil { logger.Error("failed to convert type file, err: ", err) return } return } // 旋转90度 func rotate90(m image.Image) image.Image { rotate90 := image.NewRGBA(image.Rect(0, 0, m.Bounds().Dy(), m.Bounds().Dx())) // 矩阵旋转 for x := m.Bounds().Min.Y; x < m.Bounds().Max.Y; x++ { for y := m.Bounds().Max.X - 1; y >= m.Bounds().Min.X; y-- { // 设置像素点 rotate90.Set(m.Bounds().Max.Y-x, y, m.At(y, x)) } } return rotate90 } // 旋转180度 func rotate180(m image.Image) image.Image { rotate180 := image.NewRGBA(image.Rect(0, 0, m.Bounds().Dx(), m.Bounds().Dy())) // 矩阵旋转 for x := m.Bounds().Min.X; x < m.Bounds().Max.X; x++ { for y := m.Bounds().Min.Y; y < m.Bounds().Max.Y; y++ { // 设置像素点 rotate180.Set(m.Bounds().Max.X-x, m.Bounds().Max.Y-y, m.At(x, y)) } } return rotate180 } // 旋转270度 func rotate270(m image.Image) image.Image { rotate270 := image.NewRGBA(image.Rect(0, 0, m.Bounds().Dy(), m.Bounds().Dx())) // 矩阵旋转 for x := m.Bounds().Min.Y; x < m.Bounds().Max.Y; x++ { for y := m.Bounds().Max.X - 1; y >= m.Bounds().Min.X; y-- { // 设置像素点 rotate270.Set(x, m.Bounds().Max.X-y, m.At(y, x)) } } return rotate270 } func MakeThumbnail(imagePath, savePath string) error { prefix := strings.ToLower(path.Ext("./2.jpg")) ori, err := ReadOrientation(imagePath) if err != nil { return err } file, _ := os.Open(imagePath) defer file.Close() img, _, err := image.Decode(file) if err != nil { return err } //苹果手机拍照的图片,会有方向属性Orientation, //经过Decode和Encode,编码处理后,方向属性会丢失,导致图片被旋转 switch ori { case 6: //90度图片旋转 img = rotate90(img) case 3: img = rotate180(img) case 8: img = rotate270(img) } newImg, _ := os.Create(savePath) defer newImg.Close() switch prefix { case ".jpg", ".jpeg": err = jpeg.Encode(newImg, img, &jpeg.Options{Quality: 100}) case "png": err = png.Encode(newImg, img) case "bmp": err = bmp.Encode(newImg, img) default: err = jpeg.Encode(newImg, img, &jpeg.Options{Quality: 100}) } if err != nil { logger.Error("Encode err", err) return err } return nil }