perf: WebP 二分压缩下限从 50 改为 1,匹配原图实际质量

- encodeWebPBinary 质量区间从 50~80 扩大为 1~80
- 低质量原图自动匹配低质量 WebP,不再无故回退原格式
- 回退路径中 WebP 不再重编码,避免低质量 WebP 被 quality 80 撑大
- 回退路径仅对 JPEG/PNG 重编码剥离元数据
This commit is contained in:
2026-05-31 03:16:55 +08:00
parent 48186085d8
commit 8b075f7387

View File

@ -449,27 +449,18 @@ func (ctrl *PostController) UploadImage(c *gin.Context) {
}
}
// 回退存储:重编码剥离 EXIF/元数据GIF 例外:重编码会丢失动画)
// 回退存储:JPEG/PNG 重编码剥离元数据WebP 已验证直接存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 isJPEGPNG {
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":
if ext == ".png" {
encErr = png.Encode(&buf, decImg)
default:
} else {
encErr = jpeg.Encode(&buf, decImg, &jpeg.Options{Quality: 92})
}
if encErr == nil && buf.Len() > 0 {
@ -498,8 +489,8 @@ func (ctrl *PostController) applyShortcode(post *model.Post) {
}
}
// encodeWebPBinary 二分查找 WebP 质量,找 ≤ targetBytes 的最高质量quality 50~80
// 返回 nil 表示最低质量仍超限,应由调用方回退原格式
// encodeWebPBinary 二分查找 WebP 质量,找 ≤ targetBytes 的最高质量quality 1~80
// 返回 nil 表示最低质量仍超限(几乎不可能发生),应由调用方回退原格式
func encodeWebPBinary(img image.Image, targetBytes int) []byte {
var buf bytes.Buffer
if err := webp.Encode(&buf, img, &webp.Options{Quality: 80}); err != nil {
@ -509,7 +500,7 @@ func encodeWebPBinary(img image.Image, targetBytes int) []byte {
return buf.Bytes()
}
low, high := 50, 80
low, high := 1, 80
var best []byte
for low <= high {
mid := (low + high) / 2