diff --git a/internal/controller/post_controller.go b/internal/controller/post_controller.go index 8a8eb68..49c39e8 100644 --- a/internal/controller/post_controller.go +++ b/internal/controller/post_controller.go @@ -5,9 +5,9 @@ import ( "errors" "fmt" "image" - _ "image/gif" - _ "image/jpeg" - _ "image/png" + "image/jpeg" + "image/png" + _ "image/gif" // 仅注册 GIF 解码器,不重编码(会丢失动画) "io" "net/http" "os" @@ -449,11 +449,38 @@ func (ctrl *PostController) UploadImage(c *gin.Context) { } } - // 原格式存储(GIF / 已有 WebP / 二分压缩仍超原文件大小) + // 回退存储:重新编码以剥离 EXIF/元数据(GIF 例外:重编码会丢失动画) if savePath == "" { + dataOut := data + + if isJPEGPNG || isWebP { + var decImg image.Image + var decErr error + if isWebP { + decImg, decErr = webp.Decode(bytes.NewReader(data)) + } else { + decImg, _, decErr = image.Decode(bytes.NewReader(data)) + } + if decErr == nil { + var buf bytes.Buffer + var encErr error + switch { + case isWebP: + encErr = webp.Encode(&buf, decImg, &webp.Options{Quality: 80}) + case ext == ".png": + encErr = png.Encode(&buf, decImg) + default: + encErr = jpeg.Encode(&buf, decImg, &jpeg.Options{Quality: 92}) + } + if encErr == nil && buf.Len() > 0 { + dataOut = buf.Bytes() + } + } + } + filename := fmt.Sprintf("%d_%d%s", uid, ts, ext) savePath = filepath.Join(storageDir, filename) - if err := os.WriteFile(savePath, data, 0644); err != nil { + if err := os.WriteFile(savePath, dataOut, 0644); err != nil { common.Error(c, http.StatusInternalServerError, "保存图片失败") return }