qrcode.js 无法直接加 logo 是因其仅生成二维码图像而不支持图像合成,需手动用 Canvas 先绘码再覆盖 logo;@xkeshi/qrcode 则内置 image 配置项,自动居中缩放并兼容 CORS。

qrcode.js 为什么加不了 Logo?
因为 qrcode.js(如 davidshimjs/qrcodejs)只输出点阵数据或直接渲染 SVG/Canvas,它不处理图像合成逻辑。所谓“加 logo”,本质是两次绘制:先画二维码,再用 ctx.drawImage() 覆盖中心区域。库本身没提供 logo 配置项,强行在 DOM 里叠一个 <img> 是视觉欺骗,导出图片时 logo 不会一起保存。
用 Canvas 合成 Logo 的关键三步
必须按顺序执行,漏一步就导出失败或错位:
-
canvas.width和canvas.height必须设为实际像素尺寸(比如canvas.offsetWidth * window.devicePixelRatio),不能只靠 CSS 缩放 - 调用
QRCode.toCanvas()时,{ width: canvas.width }参数值必须和 canvas 实际像素宽一致,否则模块被拉伸、扫码率暴跌 - logo 图片必须监听
onload,且x/y坐标要按模块数反推——例如总宽 200px、纠错等级 L(约 21×21 模块),中间 5×5 模块区域对应像素范围就得算:(200 - logoWidth) / 2,而不是简单写100
@xkeshi/qrcode 怎么直接配 Logo?
这个库是目前最省心的方案,支持原生 image、color、dotsOptions 等配置,不用手动 canvas 绘制:
import QRCode from '@xkeshi/qrcode';
<p>const options = {
text: '<a href="https://www.php.cn/link/b05edd78c294dcf6d960190bf5bde635">https://www.php.cn/link/b05edd78c294dcf6d960190bf5bde635</a>',
width: 200,
height: 200,
image: '/logo.png', // 自动居中、缩放、抗锯齿
margin: 10,
color: { dark: '#2563eb', light: '#fff' }
};</p><p>QRCode.toCanvas(canvas, options);立即学习“前端免费学习笔记(深入)”;
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
注意:image 路径需同源或允许 CORS,否则 canvas 会污染,toDataURL() 报 SecurityError;margin 值建议 ≥ 10,否则留白不足,部分扫码 App 识别失败。
导出高清 PNG 还是扫不出?检查这四点
容错率、留白、像素密度、尺寸比例,任意一项不达标,微信/支付宝/企业微信都可能连续扫三次才成功:
- 纠错等级至少设为
L(默认),别用Q或M—— 加 logo 后冗余空间更少 - 留白(quiet zone)必须 ≥ 4 个模块宽度,CSS padding 不算,得靠库的
margin或 canvas 手动扩边 - 导出时用
canvas.toDataURL('image/png', 1),第二个参数别省略,Safari 下缺它会降质 - logo 宽高别超二维码总宽的 20%,否则核心数据区被覆盖,纠错能力归零
真正难的不是画出来,是让不同机型、不同光线、不同扫码引擎都一次通过。这四点,少验一个,用户就在现场多举一次手机。


















