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
}