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
|
||
}
|