- 客户端压缩:保持原格式(JPG保持JPG,PNG保持PNG),不再强制转换为WebP - 提高压缩质量:最低质量从0.6提高到0.90,避免画质损失 - 启用高质量图像平滑:减少锯齿,提升画质 - 服务器端智能优化:使用MozJPEG和PNG优化算法 - 避免双重压缩:小文件(<3MB)跳过服务器端优化,只有优化效果明显(>5%)才使用 - 优化策略:优先缩小尺寸而不是降低质量,留余量给服务器端优化 技术改进: - JPEG: MozJPEG编码器,质量92%,渐进式,优化扫描 - PNG: 压缩级别6,自适应过滤,调色板优化 - 智能判断:避免不必要的双重压缩,保护画质
3.9 KiB
3.9 KiB
图片压缩优化方案说明
问题分析
双重压缩问题
- 客户端压缩:使用Canvas API,质量0.88-0.92
- 服务器端优化:使用Sharp MozJPEG,质量92%
- 风险:如果客户端已经压缩,服务器端再压缩,可能造成双重压缩,导致画质损失
优化方案
策略:避免双重压缩,智能优化
1. 客户端压缩策略(components/multimodal-input.tsx)
优化点:
- ✅ 优先缩小尺寸:如果图片太大,先缩小尺寸而不是降低质量
- ✅ 提高质量下限:最低质量从0.6提高到0.90,避免画质损失
- ✅ 留余量给服务器:目标大小设为
maxSizeMB * 0.9,留10%余量给服务器端优化 - ✅ 尺寸调整后使用高质量:如果已缩小尺寸,使用0.95质量,让服务器端做最终优化
逻辑:
如果图片 > 5MB 或 > 4K分辨率
↓
优先缩小尺寸(保持高质量)
↓
如果还是太大,才降低质量(最低0.90)
↓
输出文件(留余量给服务器端优化)
2. 服务器端优化策略(app/(chat)/api/files/upload/route.ts)
优化点:
- ✅ 智能判断:如果文件 < 3MB,跳过优化(避免双重压缩)
- ✅ 效果检查:只有优化后文件减少 > 5% 才使用,否则返回原图
- ✅ 使用更好的编码器:MozJPEG(更好的算法,而不是降低质量)
逻辑:
接收文件
↓
检查文件大小
├─ < 3MB → 跳过优化(客户端已处理)
└─ ≥ 3MB → 使用MozJPEG/PNG优化
↓
检查优化效果
├─ 减少 > 5% → 使用优化结果
└─ 减少 ≤ 5% → 使用原图
工作流程
场景1:小文件(< 5MB,< 4K)
客户端:直接返回原图(免检通道)
服务器:< 3MB,跳过优化
结果:原图直接存储,无压缩
场景2:中等文件(5-8MB,< 4K)
客户端:可能轻微压缩(质量0.90-0.95)
服务器:< 3MB,跳过优化
结果:客户端压缩后存储,无双重压缩
场景3:大文件(> 8MB 或 > 4K)
客户端:缩小尺寸 + 高质量压缩(质量0.90-0.95)
↓
服务器:≥ 3MB,使用MozJPEG优化
↓
检查优化效果
├─ 减少 > 5% → 使用优化结果
└─ 减少 ≤ 5% → 使用原图(避免双重压缩)
优化效果
避免双重压缩
- ✅ 小文件(< 3MB):服务器端跳过优化
- ✅ 优化效果检查:只有明显优化才使用
- ✅ 客户端提高质量下限:0.6 → 0.90
画质保护
- ✅ 客户端优先缩小尺寸,而不是降低质量
- ✅ 服务器端使用更好的编码器(MozJPEG),而不是降低质量
- ✅ 智能判断,避免不必要的处理
文件大小
- ✅ 客户端留10%余量给服务器端优化
- ✅ 服务器端使用MozJPEG(压缩率高15-25%)
- ✅ 双重优化效果更好(但避免双重压缩)
技术细节
客户端压缩参数
- 起始质量:0.92(尺寸未调整)或 0.95(尺寸已调整)
- 最低质量:0.90(避免画质损失)
- 目标大小:
maxSizeMB * 0.9(留余量) - 图像平滑:
high(减少锯齿)
服务器端优化参数
- 优化阈值:3MB(小于此值跳过优化)
- 效果阈值:5%(只有减少超过5%才使用)
- JPEG质量:92%(高质量)
- PNG质量:100%(无损)
预期效果
| 文件大小 | 客户端处理 | 服务器端处理 | 最终结果 |
|---|---|---|---|
| < 3MB | 原图或轻微压缩 | 跳过优化 | 高质量,无双重压缩 |
| 3-8MB | 高质量压缩 | 智能优化 | 高质量,单次优化 |
| > 8MB | 缩小尺寸+高质量 | MozJPEG优化 | 高质量,双重优化(但避免双重压缩) |
总结:通过智能判断和效果检查,避免不必要的双重压缩,同时保证画质和文件大小优化。