package logic import ( "dubbo.apache.org/dubbo-go/v3/common/logger" "errors" "fmt" "fonchain-fiee/pkg/config" "fonchain-fiee/pkg/e" "github.com/fonchain_enterprise/utils/objstorage" "github.com/rwcarlsen/goexif/exif" "golang.org/x/image/bmp" "image" "image/jpeg" "image/png" "io/ioutil" "os" "path" "strings" ) type IUpload interface{} type Upload struct{} // 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 } func (u *Upload) PutBos(filePath string, mediaType string, needRemove bool) (url string, err error) { BOSClient, err := objstorage.NewOSS(config.ConfigData.Oss.AccessKeyId, config.ConfigData.Oss.AccessKeySecret, config.ConfigData.Oss.Endpoint) if err != nil { logger.Errorf("PutBos NewOOS err ", err) err = errors.New(e.GetMsg(e.ErrorUploadBos)) return } f, err := os.Open(filePath) if err != nil { logger.Errorf("PutBos Open err %+v", err.Error()) return } fileBytes, _ := ioutil.ReadAll(f) f.Close() //删除本地文件 if needRemove { os.Remove(filePath) } filePath = strings.Replace(filePath, "./runtime", "", 1) var objectName string = fmt.Sprintf("%s/%s%s", config.ConfigData.Oss.BaseDir, config.Env, filePath) _, err = BOSClient.PutObjectFromBytes(config.ConfigData.Oss.BucketName, objectName, fileBytes) if err != nil { logger.Errorf("PutBos PutObject err %+v", err.Error()) err = errors.New(e.GetMsg(e.ErrorUploadBos)) return } //url = fmt.Sprintf("%s%s%s/%s", config.BosHttp, config.BosBucketName, config.BosUrl, objectName) url = fmt.Sprintf("%s/%s", config.ConfigData.Oss.CdnHost, objectName) return }