多模态Agent上传图片:前端压缩格式与预览实战

接了个图片问答的需求:用户传张图,AI 看图回答。听着就是个 <input type=file>,真做下去才知道前端要替用户兜多少事------几十兆的原图直接传,请求超时;HEIC 格式后端不认;预览图把内存吃爆。一篇实战,把上传这条链路的脏活拆开讲。

先压,别让用户传原图

现在手机随手一拍就是十几兆,原图传上去既慢又烧带宽,多模态模型其实也不需要那么高分辨率。前端用 canvas 等比缩到长边 1568px 左右(多数视觉模型的友好尺寸)再传,体积能砍九成:

ini 复制代码
async function compress(file: File, maxEdge = 1568, quality = 0.82): Promise<Blob> {
  const bitmap = await createImageBitmap(file);
  const scale = Math.min(1, maxEdge / Math.max(bitmap.width, bitmap.height));
  const w = Math.round(bitmap.width * scale);
  const h = Math.round(bitmap.height * scale);
  const canvas = new OffscreenCanvas(w, h);
  const ctx = canvas.getContext('2d')!;
  ctx.drawImage(bitmap, 0, 0, w, h);
  bitmap.close(); // 重要,及时释放,否则内存涨得吓人
  return canvas.convertToBlob({ type: 'image/jpeg', quality });
}

bitmap.close() 那行别漏。我做批量上传时没释放,连传十几张内存直接飙到几百兆,移动端 webview 当场崩。OffscreenCanvas 还能放进 Web Worker 压,不卡主线程,长列表上传体验好很多。

HEIC 是个大坑

iPhone 默认存 HEIC,浏览器 <img> 和 canvas 大多不认,createImageBitmap 直接抛错。我一开始没考虑,苹果用户上传全军覆没,测试机是安卓还没测出来,上线才暴雷。

处理方式:检测到 HEIC 先用 heic2any 之类转成 jpeg 再走压缩。代价是这个库 gzip 后小两百 KB,我做了动态 import,只有真遇到 HEIC 才加载,别让所有用户为少数格式买单:

javascript 复制代码
async function normalize(file: File): Promise<File> {
  if (/heic|heif/i.test(file.type) || /.heic$/i.test(file.name)) {
    const { default: heic2any } = await import('heic2any'); // 按需加载
    const blob = await heic2any({ blob: file, toType: 'image/jpeg' });
    return new File([blob as Blob], file.name.replace(/.heic$/i, '.jpg'), { type: 'image/jpeg' });
  }
  return file;
}

预览图用 objectURL,记得 revoke

预览别用 FileReader 读 base64------大图转 base64 又慢又占内存,还会把 DOM 撑大。用 URL.createObjectURL 几乎零成本,但必须配对 revoke,否则这块内存到页面关都不释放:

ini 复制代码
const url = URL.createObjectURL(file);
previewEl.src = url;
previewEl.onload = () => URL.revokeObjectURL(url); // 加载完立刻回收

删除某张待传图片时也要 revoke 对应的 url。我有个版本忘了在删除分支里回收,用户反复添加删除几十次后,内存只涨不跌,典型的泄漏。

上传前的体面校验

别等传到后端才报「格式不支持」。前端先把住门------类型白名单、单张大小上限、张数上限,错误就地提示,省一次往返也省用户的脾气:

kotlin 复制代码
function validate(file: File) {
  const ok = ['image/jpeg', 'image/png', 'image/webp', 'image/heic'];
  if (!ok.includes(file.type)) return '只支持 JPG/PNG/WebP/HEIC';
  if (file.size > 20 * 1024 * 1024) return '单张不能超过 20MB';
  return null;
}

一个没做完美的

压缩质量我固定在 0.82,对照片够用,但用户传的若是带细密文字的截图,压完字会糊,影响模型识别。理想做法是按内容自适应质量,我评估了下投入产出比,暂时没做,先在文案里提示「文字截图建议原图」绕过去。算个偷懒,但当下够用。

多模态那头的模型能力我直接接讯飞 这类 MaaS 的现成 API,不操心算力和模型怎么部署,前端只把图片处理这条链路打磨干净。

你们上传链路还有啥隐形坑?HEIC 之外我估计还有冷门格式,评论区补补刀。

相关推荐
小和尚同志5 小时前
小黑插图 Skill:从 11.7k star 的 Codex 专属,到 Claude Code 能用的平替
人工智能·aigc
高洁015 小时前
孪生不止在工厂:能源、医疗与农业
人工智能·深度学习·transformer·知识图谱·tornado
外域速览5 小时前
智谱50亿美元押注AI自训练
大数据·人工智能
人工智能培训5 小时前
孪生不止在工厂:能源、医疗与农业
大数据·人工智能
米小虾5 小时前
让模型说"我不知道",比让它答对更难:放弃文本生成能换来什么
人工智能
新新学长搞科研5 小时前
【SPIE出版】2026年人工智能、新材料与新能源国际学术会议(AINMNE 2026)
人工智能·新能源·新材料
野生技术架构师6 小时前
2026 Java 面试全套总结,八股 + 场景 + AI 相关面试考点
java·人工智能·面试
米小虾6 小时前
不写出来的思考:把 Transformer 的层循环起来,是第三条 scaling 轴还是省错了地方?
人工智能
A.说学逗唱的Coke6 小时前
【大模型专题】别再用 HTTP 直连 Agent 了:用 Kafka 承载 A2A 协议,从 PoC 走到生产
人工智能·kafka·a2a
资讯综合6 小时前
2026企业AI平台选型指南:多维视角下的主流方案解析
人工智能