feat(ux): 图片选图即压缩,上传体积从 MB 级降到 KB 级

服务端早已把静态图转 WebP、长边限 1600(storage.GeneralEncodeSpec),但上传这一跳
发生在压缩之前:手机拍的 4~8MB 照片要先原样传完才能被缩小,移动网络 1~2 Mbps 下
要等几十秒,超过 5MB 校验的直接被拒、连写好的正文一起丢。

现在选图后先在浏览器内压缩,再随表单上传:
- canvas → WebP,长边 1600、质量 0.8(与服务端同档),一张照片通常降到 200~400KB
- createImageBitmap + imageOrientation:from-image 摆正 EXIF,老浏览器回退不带选项
- submit capture 兜底:选图立刻提交时先等压缩完成再真正 submit

三条安全边界(缺一不可,否则会「压出比原图更差的结果」):
- GIF/SVG 跳过:canvas 会把 GIF 画成静止首帧、SVG 栅格化
- 压完不到原体积 85% 退回原图:已优化小图重编码反而更大
- 透明 PNG 优先 WebP(支持 alpha),不支持 WebP 编码时退回 PNG 而非 JPEG(否则透明变黑)

实测(WSL headless Chromium + CDP):4.6MB PNG → 11.7KB WebP(0.3%),
小图原样保留、GIF 跳过。

顺带加 dev/sync-wsl.sh:把同步脚本里 rsync --delete 误删目标机 conf/app.ini 的坑
固化掉(该文件含 DB 密码与对象存储密钥,不在源目录里,必须 exclude)。
This commit is contained in:
tamakyi
2026-10-29 18:26:04 +08:00
parent 4e574ac64a
commit f9aaef17e5
3 changed files with 222 additions and 0 deletions
+31
View File
@@ -0,0 +1,31 @@
#!/usr/bin/env bash
# 把 Windows 侧工作区同步到 WSL 里的测试部署目录。
#
# 为什么不能直接 rsync --delete:WSL 侧有几份「只存在于目标机」的文件,
# 源目录里没有它们,--delete 会把它们当多余文件删掉:
# - conf/app.ini 本地测试配置(数据库密码、对象存储密钥;模板见 dev/wsl-app.ini)
# 第一次踩这个坑时整份 app.ini 被删,服务器重启后起不来。
#
# 用法:在仓库根目录执行
# bash dev/sync-wsl.sh
set -euo pipefail
SRC="$(cd "$(dirname "$0")/.." && pwd)"
DST=/home/tamakyi/tb/src
cd "$SRC"
tar -cf - \
--exclude=.git \
--exclude=outputs \
--exclude=.workbuddy \
. 2>/dev/null |
wsl -d Debian -e bash -c '
set -e
DST=/home/tamakyi/tb/src
rm -rf /tmp/tbsync && mkdir -p /tmp/tbsync
tar -xf - -C /tmp/tbsync
# 只同步代码与资源,绝不动目标侧的 conf/app.ini
rsync -a --delete --exclude "conf/app.ini" /tmp/tbsync/ "$DST"/
rm -rf /tmp/tbsync
echo "SYNCED -> $DST"
'