120 lines
2.8 KiB
Go
120 lines
2.8 KiB
Go
|
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
|
|||
|
}
|