真正可上传分享的圆形头像必须用canvas像素级裁剪:先等比缩放居中截取正方形,再用clip()实现真圆形裁剪,最后转blob上传,避免css遮罩或base64导致的后端接收矩形图问题。

网页端用 Canvas 一键生成圆形头像,核心是“先裁正方、再套圆”,不能只靠 CSS 视觉遮罩。真正可上传、可分享的圆形头像,必须通过 canvas 像素级操作完成,否则后端收到的仍是原始矩形图。
准备图片并确保加载完成
用户选择图片后(<input type="file">),需监听 load 事件再执行绘制,避免图片未就绪导致 canvas 空白:
- 用
URL.createObjectURL(file)快速生成本地预览地址 - 创建
new Image()实例,设置img.src后绑定onload回调 - 不建议直接用 base64,大图易卡顿,且部分旧版 Safari 对 data URL 长度有限制
统一缩放为正方形再裁圆
原始图片常为长图或竖图,直接画圆会拉伸或留白。正确做法是先等比缩放+居中截取为正方形,再套圆形蒙版:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 计算目标尺寸:
size = Math.min(img.width, img.height) - canvas 宽高均设为
size,保证输出为标准正方区域 -
drawImage的源坐标需偏移,例如:(img.width - size) / 2和(img.height - size) / 2,实现居中截取
用 clip() 实现真裁剪(不是遮罩)
关键在 ctx.clip() —— 它让后续所有绘制只在指定路径内生效,这才是像素级裁剪:
- 先调
ctx.save()保存状态,防止影响其他绘制 - 用
ctx.arc(centerX, centerY, radius, 0, Math.PI * 2)画完整圆路径 - 立刻执行
ctx.clip(),否则arc()只画线,不裁剪 - 再调
ctx.drawImage(...),图像自动被限制在圆形区域内 - 最后
ctx.restore()恢复上下文,保持代码健壮性
导出为可用文件并上传
生成 canvas 后,需转成 Blob 才能放进 FormData 上传:
- 用
canvas.toBlob(callback, 'image/png', 0.92)异步导出,PNG 更适合头像(支持透明背景,无 JPEG 白边) - 不要用
toDataURL()→ base64 → atob 解码,体积膨胀约 33%,且增加 CPU 开销 - 若需模拟原生文件对象,可封装:
new File([blob], 'avatar.png', {type: 'image/png'}) - 上传前检查
blob.size,超 2MB 可提示或自动降质重裁(如缩小width参数)










