Skip to content

Commit

Permalink
Merge pull request #229 from xuewenG/fix/unexpected-image-rotation
Browse files Browse the repository at this point in the history
修复生成缩略图的方向不正确,修复删除文件报错
  • Loading branch information
xuewenG authored Dec 10, 2024
2 parents b2b3c8f + 54cb7bd commit 574ad67
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 86 deletions.
93 changes: 12 additions & 81 deletions backend/handler/compress.go
Original file line number Diff line number Diff line change
@@ -1,106 +1,37 @@
package handler

import (
"image"
"image/jpeg"
"image/png"
"io"
"net/http"
"os"

"github.com/disintegration/imaging"
)

// CompressImage 接收图片路径并进行压缩
// 支持jpg和png格式的图片,并且会校验MIME类型
// 如果图片类型不是jpg或png,则不进行处理
// 返回错误信息
func CompressImage(f FileHandler, filePath string, thumbFilepath string, quality int) error {
// 打开文件
file, err := os.Open(filePath)
if err != nil {
return err
}
defer file.Close()
func CompressImage(f FileHandler, originImagePath string, thumbImagePath string, quality int) error {
f.base.log.Debug().Msgf("start compressing image, originImagePath=%s, quality=%d", originImagePath, quality)

// 获取文件信息
fileInfo, err := file.Stat()
originImage, err := imaging.Open(originImagePath, imaging.AutoOrientation(true))
if err != nil {
f.base.log.Error().Msgf("failed to open image: %v", err)
return err
}

// 读取文件的前512字节
buffer := make([]byte, 512)
_, err = file.Read(buffer)
if err != nil && err != io.EOF {
return err
}

// 重置文件指针到开头
_, err = file.Seek(0, 0)
thumbImageFile, err := os.Create(thumbImagePath)
if err != nil {
f.base.log.Error().Msgf("failed to create thumb image: %v", err)
return err
}
defer thumbImageFile.Close()

// 检测MIME类型
contentType := http.DetectContentType(buffer)

// 解码图片
img, format, err := image.Decode(file)
compressedImage := imaging.Resize(originImage, 600, 0, imaging.Lanczos)
err = imaging.Encode(thumbImageFile, compressedImage, imaging.JPEG)
if err != nil {
f.base.log.Error().Msgf("failed to save image: %v", err)
os.Remove(thumbImagePath)
return err
}
dst, err := os.Create(thumbFilepath)
if err != nil {
f.base.log.Error().Msgf("打开目标图片异常:%s", err)
return err
}
// 复制图片
if _, err = io.Copy(dst, file); err != nil {
f.base.log.Error().Msgf("复制图片异常:%s", err)
return err
}

// 校验MIME类型
switch format {
case "jpeg", "jpg":
if contentType != "image/jpeg" {
f.base.log.Error().Msgf("不支持的图片格式:%s", contentType)
return err
}
// 重新打开文件以写入压缩后的图片
file, err = os.OpenFile(thumbFilepath, os.O_WRONLY|os.O_TRUNC, fileInfo.Mode())
if err != nil {
return err
}
defer file.Close()
dstImage := imaging.Resize(img, 600, 0, imaging.Lanczos)
// 使用JPEG格式压缩图片
err = jpeg.Encode(file, dstImage, &jpeg.Options{Quality: quality})
if err != nil {
return err
}
case "png":
if contentType != "image/png" {
f.base.log.Error().Msgf("不支持的图片格式:%s", contentType)
return err
}
// 重新打开文件以写入压缩后的图片
file, err = os.OpenFile(thumbFilepath, os.O_WRONLY|os.O_TRUNC, fileInfo.Mode())
if err != nil {
return err
}
defer file.Close()
dstImage := imaging.Resize(img, 600, 0, imaging.Lanczos)

// 使用PNG格式压缩图片
err = png.Encode(file, dstImage)
if err != nil {
return err
}
default:
f.base.log.Error().Msgf("不支持的图片格式:%s", contentType)
}

f.base.log.Debug().Msgf("compressing image finished, originImagePath=%s, quality=%d", originImagePath, quality)
return nil
}
22 changes: 17 additions & 5 deletions backend/handler/memo.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/google/uuid"
"github.com/kingwrcy/moments/db"
fs_util "github.com/kingwrcy/moments/util"
"github.com/kingwrcy/moments/vo"
"github.com/labstack/echo/v4"
"github.com/rs/zerolog"
Expand Down Expand Up @@ -61,17 +62,28 @@ func (m MemoHandler) RemoveImage(c echo.Context) error {
if err != nil {
return FailResp(c, ParamError)
}

if !strings.HasPrefix(req.Img, "/upload/") {
return SuccessResp(c, h{})
}

img := strings.ReplaceAll(req.Img, "/upload/", "")
if err := os.Remove(filepath.Join(m.base.cfg.UploadDir, img)); err != nil {
return FailRespWithMsg(c, ParamError, fmt.Sprintf("删除图片失败:%s", err))

imageFilePath := filepath.Join(m.base.cfg.UploadDir, img)
if fs_util.Exists(imageFilePath) {
if err := os.Remove(imageFilePath); err != nil {
return FailRespWithMsg(c, ParamError, fmt.Sprintf("删除图片失败:%s", err))
}
}
thumbImg := strings.ReplaceAll(req.Img+"_thumb", "/upload/", "")
if err := os.Remove(filepath.Join(m.base.cfg.UploadDir, thumbImg)); err != nil {
FailRespWithMsg(c, ParamError, fmt.Sprintf("删除缩略图失败:%s", err))

thumbImageFilename := strings.ReplaceAll(req.Img+"_thumb", "/upload/", "")
thumbImageFilePath := filepath.Join(m.base.cfg.UploadDir, thumbImageFilename)
if fs_util.Exists(thumbImageFilePath) {
if err := os.Remove(thumbImageFilePath); err != nil {
m.base.log.Error().Msgf("删除缩略图失败, thumbImageFilePath=%s, err=%v", thumbImageFilePath, err)
}
}

return SuccessResp(c, h{})
}

Expand Down
12 changes: 12 additions & 0 deletions backend/util/fs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package fs_util

import "os"

func Exists(path string) bool {
_, err := os.Stat(path)
if err != nil {
return os.IsExist(err)
}

return true
}

0 comments on commit 574ad67

Please sign in to comment.