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
相关产品推荐
相关产品推荐

