You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

HTML5 Canvas加文字后用jsPDF生成PDF出现文字模糊如何解决?

问题核心原因

你遇到的文字模糊本质是Canvas物理分辨率不足+PDF渲染时放大拉伸导致的:

  • 二维码是大块纯色像素,放大后边缘依旧清晰,所以看不出模糊
  • 文字是次像素平滑渲染的,一旦原始Canvas像素密度不够,放大后边缘就会发虚
  • 你补充提到的「原始Canvas尺寸远小于PDF中显示尺寸」就是直接诱因,低分辨率小图被强制拉大,文字自然模糊

具体修改步骤

1. 适配高DPI提升Canvas物理分辨率

先根据设备像素比(打印场景建议至少用2~3倍倍率,兼容300DPI打印需求)放大Canvas的实际像素尺寸,再对上下文进行缩放,原有绘制逻辑不需要调整:

printQRCode(){
const baseWidth = 150; // PDF中要显示的逻辑宽度,保持你原来的数值
// 新增:适配高DPI,打印场景固定用3倍倍率即可覆盖绝大多数显示、打印场景
const dpr = Math.max(window.devicePixelRatio || 2, 3);
const actualWidth = baseWidth * dpr;
const ratio = 8 / 100;
const fontSize = baseWidth * ratio; // 逻辑字号保持不变
const text = `[${this.getCode()}]`;

toCanvas(text,
{errorCorrectionLevel: 'H', width: actualWidth}, // 这里传放大后的实际宽度生成二维码
(_err, canvas) => {
  const ctx = canvas.getContext('2d');
  // 新增:缩放上下文,后续绘制用逻辑尺寸即可,自动对应到放大后的物理像素
  ctx.scale(dpr, dpr);
  this.setOptimalFontSizeForCanvas(ctx, fontSize, text, baseWidth); // 传入逻辑宽度即可
  ctx.fillText(text, this.getCenterPositionForCanvasText(ctx, text, baseWidth), baseWidth - 5);
  const contentDataURL = canvas.toDataURL('image/png', 1.0); // 导出无压缩的PNG保证清晰度

  const pdf = new jsPDF('p', 'px', 'a4');
  // 关键:插入图片时,显示尺寸用你需要的逻辑尺寸baseWidth,不要用canvas.width
  pdf.addImage(contentDataURL, 'PNG', 0, 0, baseWidth, baseWidth);
  pdf.autoPrint();
  pdf.output('dataurlnewwindow');
});
}

2. 可选优化(如果还有轻微模糊)

如果用px单位还是有适配问题,可以把jsPDF单位换成pt(PDF原生单位,1pt=1/72英寸),转换逻辑如下:
1英寸=96px,所以1px = 72/96 = 0.75pt,你需要的150px宽度对应112.5pt,初始化PDF时用new jsPDF('p', 'pt', 'a4'),插入图片时宽高传112.5即可。


补充问题解答:addImage宽高计算规则

传给pdf.addImage的宽高是你希望这个图片在PDF里最终显示的尺寸,和Canvas本身的物理像素尺寸无关:

  • 如果你用px作为PDF单位,就传你原来设计的显示宽度(比如150)
  • 如果你用pt作为PDF单位,就按显示px值 * 0.75换算成pt值
  • 高DPR放大后的Canvas物理尺寸只用来提升像素密度,不要作为插入PDF的显示尺寸使用

内容的提问来源于stack exchange,提问作者sirzento

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 15:39:01