webp fix v1

This commit is contained in:
tamakyi
2026-10-15 11:41:19 +08:00
parent 6ffc87e4a8
commit e4457e3da4
15 changed files with 1297 additions and 39 deletions
+25
View File
@@ -25,6 +25,31 @@
编辑前用 Python 数 `b'\r\n'` 确认(`grep -c $'\r'` 不可靠)。`gofmt -l` 会把 CRLF 文件误报为未格式化。
格式化统一走 `dev/gofmt_keep_crlf.py <files>`。
- `internal/security/censor/censor.go`、`text_test.go` 有升级前就存在的空格缩进,别顺手 gofmt。
- ⚠️ **`go build -overlay` 不能替换 GOMODCACHE 下的文件**(Go 直接报错拒绝)。
要在本机类型检查依赖 cgo 的真实代码(如 `internal/storage/s3.go`),唯一可行方案:
**`tar` 复制项目到临时目录 → 在副本里 `go mod edit -replace <cgo依赖>=../本地stub` → 编译/测试**。
副本约 15MB、编译约 2~7 分钟。**别用 `s3stub` overlay 检查 s3.go 本身**——overlay 会把 s3.go
换成桩,等于根本没检查它(只能检查调用方)。见 2026-10-15 的批次 A 落地记录。
- 行尾确认:`internal/storage/s3.go` = LF,`route/question/page.go` = CRLF。
- ⚠️ **依赖真实编码器的端到端断言在本机不成立**(webp 被 replace 成桩,Encode 不产出字节)。
这类测试要写成「检测到桩就 `t.Skip`」,否则 CI/本机表现不一致。
## 图片上传与编码(`internal/storage/s3.go`)
- 三档编码规格 `EncodeSpec{MaxSide, Quality}`:头像 512/q78、背景 1920/q80、通用 1600/q80。
头像依据:模板最大展示 120px(`.tb-frame-avatar`),前端 cropper 输出上限 512。
⚠️ 档位只作用于**新上传**,线上已有图片不会被重压。
- 所有转换分支都有 `len(webp) >= len(原图)` 回退——线框图/小图标上有损 WebP 反而更大
(实测 200x200 线框图 PNG 652B vs WebP 908B),不加兜底会越转越大。
- **EXIF 方向必须在转码前归一**(`exif.go` 手工解析 APP1,无外部依赖)。
`image.Decode` 与 Pillow 默认都不读 EXIF;**转成 WebP 后 EXIF 被丢弃、方向永久丢失**。
顺序铁律:**先归一方向 → 再限边缩放**(归一会交换宽高)。
- GIF 帧数上限 `maxGIFFrames = 200`:`CheckPixelLimit` 只看逻辑屏尺寸,
几百帧的大 GIF 体积小但能让 `cwebp` 长时间吃 CPU。
- **method=6 已评估并否决**:实测耗时只增 1.2~1.9x(不是原以为的 5~10x),
但体积只省 ~3%,1C1G 上不划算。
- `cwebp` 缺失时的 GIF 静默回退已加 `logrus.Warn`;生产机(裸 Linux)已确认装有 `cwebp`。
## 内容审核