确保canvas图片在各设备清晰的关键是同步处理dpr、逻辑尺寸、css显示尺寸及重绘缩放:设canvas宽高为容器尺寸×dpr,css缩回原大小,并调用ctx.scale(dpr,dpr);html2canvas导出需设scale=dpr、usecors=true,并监听图表渲染完成事件。

要让 H5 中 Canvas 生成的图片在各种设备上都清晰,关键不是“单纯放大 canvas 尺寸”,而是同步处理设备像素比(DPR)、逻辑尺寸、CSS 显示尺寸和重绘缩放。尤其在图表类场景中,文字、线条、刻度等细节极易模糊,必须针对性优化。
确保 canvas 内在分辨率匹配高清屏
Canvas 的 width 和 height 属性决定其绘图上下文的逻辑像素数量,而 CSS 的 width/height 只控制显示大小。若两者不匹配 DPR,就会模糊。
- 获取当前设备像素比:
const dpr = window.devicePixelRatio || 1 - 设 canvas 属性为:
canvas.width = container.clientWidth * dpr,canvas.height = container.clientHeight * dpr - 用 CSS 把 canvas 视觉尺寸缩回原始容器大小:
canvas.style.width = container.clientWidth + 'px',同理设 height - 调用
ctx.scale(dpr, dpr),使后续所有绘图坐标(如fillText、lineTo)自动适配高分屏
html2canvas 导出前的关键配置项
图表常由 DOM 渲染(如 ECharts、Chart.js 容器),用 html2canvas 转图时,默认输出易模糊。需显式提升渲染质量:
- 启用
useCORS: true,确保跨域图表图片(如图标、背景图)能正常加载 - 设置
scale: window.devicePixelRatio(推荐值 2 或更高),强制 html2canvas 在高倍率下绘制 - 添加
logging: false和allowTaint: true(仅内网/可信环境),避免因资源拦截中断渲染 - 对含 SVG 或复杂 CSS 的图表,可加
foreignObjectRendering: true(v2+ 版本支持)提升兼容性
图表重绘与导出时机要精准
很多模糊问题其实源于“导出太快”——图表库尚未完成最终渲染或字体未就绪。
- 不要在图表初始化后立刻调用 html2canvas,应监听图表的
finished或rendered事件(如 ECharts 的chart.on('finished', ...)) - 若图表含自定义字体(如 iconfont、特殊中文字体),需用
document.fonts.load()确保加载完成再截图 - 对动态动画图表,建议暂停动画(如
chart.clearAnimation())后再导出,避免截到中间帧 - 导出前手动触发一次
chart.resize(),确保布局已按最新容器尺寸计算完毕
导出图片格式与压缩权衡
toDataURL 默认生成 base64 PNG,但体积大;转 JPEG 可控压缩,但可能损失文字锐度。
- 优先用
canvas.toDataURL('image/png')—— PNG 无损,适合含文字、坐标轴、细线的图表 - 若必须用 JPEG,至少设质量参数:
canvas.toDataURL('image/jpeg', 0.95),低于 0.9 容易出现文字锯齿 - 避免直接用 Canvas2Image.js 等封装库默认压缩,它常隐式降质;建议手写导出逻辑,完全可控











