如何在React中使用QRCode库将Logo显示在生成的二维码上方?
解决方案
要在二维码上方添加Logo,需要解决三个核心问题:图片加载异步、正确绘制Logo到Canvas、确保图片路径在React中有效。以下是修改后的完整代码及关键说明:
修改后的代码
// 先导入Logo图片(React中必须这样处理静态资源,否则打包后路径会失效) import Logo from 'src/pages/Client/Turns/logo.png'; const generateQRCode = async (rowData) => { const { N_turno, orden, bahia, proceso_t, n_placa, cond_info } = rowData; const url = `${BASE_API}/${auth.me.tenant}/documentos/qr/`; const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: `n_orden=${orden}&n_turno=${N_turno}&n_proceso=${proceso_t}`, }); const data = await response.json(); const qrCanvas = document.createElement('canvas'); qrCanvas.height = 700; // 增加高度,给Logo预留空间(原600→700) qrCanvas.width = 200; // 1. 等待Logo图片加载完成(异步处理) const logoImg = await new Promise((resolve, reject) => { const img = new Image(); img.src = Logo; img.onload = () => resolve(img); img.onerror = reject; }); const ctx = qrCanvas.getContext('2d'); // 2. 绘制Logo到Canvas顶部居中位置 const logoWidth = 120; // 设置Logo宽度,可根据需求调整 const logoHeight = (logoImg.height / logoImg.width) * logoWidth; // 保持宽高比 const logoX = (qrCanvas.width - logoWidth) / 2; const logoY = 20; // Logo距离顶部的间距 ctx.drawImage(logoImg, logoX, logoY, logoWidth, logoHeight); // 3. 绘制二维码,调整位置到Logo下方(y轴偏移Logo高度+间距) await QRCode.toCanvas(qrCanvas, data.qr_content, { margin: 15, scale: 10, // 指定二维码绘制的起始位置,避免覆盖Logo x: 0, y: logoY + logoHeight + 20 // Logo底部到二维码顶部的间距20px }); // 4. 添加底部文本(y轴位置也要对应调整,因为Canvas高度增加了100) ctx.font = '25px arial'; ctx.textAlign = 'center'; ctx.fillText(`Driver: ${cond_info}`, qrCanvas.width / 2, qrCanvas.height - 120); ctx.fillText(`Order: ${orden}`, qrCanvas.width / 2, qrCanvas.height - 90); ctx.fillText(`Plate: ${n_placa}`, qrCanvas.width / 2, qrCanvas.height - 60); ctx.fillText(`Turn: ${data.n_turno}`, qrCanvas.width / 2, qrCanvas.height - 30); ctx.fillText(`Bay: ${bahia}`, qrCanvas.width / 2, qrCanvas.height - 1); // 生成并下载二维码 const qrImg = qrCanvas.toDataURL(); const downloadLink = document.createElement('a'); downloadLink.href = qrImg; downloadLink.download = `qr-code${rowData.orden}.png`; downloadLink.click(); };
关键修改说明
- 图片路径处理:React中静态资源必须通过
import导入,否则打包后无法正确访问图片文件。 - 异步加载Logo:用Promise包裹图片的
onload事件,确保图片加载完成后再绘制,避免出现空白或绘制失败。 - Canvas布局调整:
- 增加Canvas高度,为Logo预留顶部空间;
- 指定二维码的绘制起始
y坐标,让它在Logo下方显示,避免被覆盖; - 计算Logo的居中位置和缩放尺寸,保持图片比例不变。
- 简化DOM操作:原代码中创建的
qrContainer和qrWrapper是多余的,直接用Canvas生成的DataURL创建下载链接即可。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

