浏览器图片压缩是“解码—变换—编码”链路:读取 File,把压缩字节解码为像素,在 Canvas 上缩放或编辑,再编码为新的 JPEG、WebP、PNG 或 AVIF Blob。
质量滑块只控制一部分结果。像素尺寸、原图噪声、格式、透明通道、元数据、重复编码和编解码支持,往往比把质量从 0.82 调到 0.78 更重要。
本地处理链
createImageBitmap、img 或 ImageDecoder 解码 File;Canvas 提供缩放、裁剪、旋转和合成表面;Canvas.toBlob 或本地编解码器生成输出。
Blob 通过 createObjectURL 预览和下载,每个阶段都由浏览器 API 完成,无需上传。
const bitmap = await createImageBitmap(file);
ctx.drawImage(bitmap, 0, 0, width, height);
const blob = await new Promise<Blob>((resolve) =>
canvas.toBlob((value) => resolve(value!), 'image/webp', 0.82)
);先缩尺寸,再激进降质量
4000 × 3000 照片有 1200 万像素,1000 × 750 只需 75 万,是十六分之一。先删除不必要尺寸,通常比把全分辨率压到极低质量更小且瑕疵更少。
除非故意变形,否则保持宽高比;截图与线条图的滤波和格式策略应区别于照片。
质量只是编码器提示
Canvas 质量通常是 0 到 1 的有损编码提示,不是统一画质百分比。同一个 0.8 在不同浏览器和格式中会产生不同体积和瑕疵。
PNG 通常无损,可能忽略质量。Canvas 无法编码 AVIF 时可用 WASM;应验证返回 Blob 的真实 type。
格式决定结果
JPEG 适合无透明照片;PNG 保留锐利边缘和 alpha,但照片体积大;WebP 支持有损、无损和透明;AVIF 效率高但编码慢。
文字截图用低质量 JPEG 容易变糊,透明图片转 JPEG 前必须先合成背景。
元数据、方向与色彩
Canvas 重编码通常移除 GPS、相机参数、时间与版权等 EXIF,可能改善隐私,也可能清除来源信息;导出前要应用方向。
色彩 Profile 和广色域可能被规范化,印刷、医疗、法律与归档流程应使用受控软件验证。
内存与验收
压缩文件解码后约占宽 × 高 × 四字节 RGBA,再加源、Canvas、中间和输出。应限制像素、串行处理批次、使用 Worker、关闭 ImageBitmap 并释放旧 URL。
按实际尺寸和 100% 检查文字、人脸、渐变与边缘,验证尺寸、MIME、透明、方向和体积,避免反复有损导出。
- 先缩尺寸。
- 保留原图。
- 验证 MIME 与尺寸。
- 检查元数据。
- 避免反复 JPEG/WebP 编码。
总结
可靠压缩结合尺寸缩减、适合内容的格式、经过测量的质量、明确元数据行为、内存控制和输出检查。Canvas 与 Blob 提供核心链路。