使用qr-code-styling在Safari下载二维码时中心Logo缺失求助
Safari下载带Logo的二维码缺失中心Logo问题解决
我使用qr-code-styling生成带中心Logo的二维码,页面上Chrome和Safari都能正常显示Logo,但在Safari中点击下载按钮保存为PNG时,下载的二维码丢失了中心Logo,Chrome下载则完全正常。
相关代码
React组件代码
const qrRef = React.useRef<HTMLDivElement>(null); const qrCodeRef = React.useRef<QRCodeStyling | null>(null); const downloadQRCode = (evt: React.FormEvent) => { qrCodeRef.current?.download({ name: user?.username, extension: "png", }); }; useEffect(() => { if (qrRef.current) { const qrCode = new QRCodeStyling({ width: 160, height: 160, type: "svg", data: "https://example.com/" + user?.username, image: "/qr_logo.png", dotsOptions: { color: "#000000", }, backgroundOptions: { color: "#ffffff", }, imageOptions: { crossOrigin: "anonymous", margin: 4, }, }); // 清空容器 qrRef.current.innerHTML = ""; qrCode.append(qrRef.current); qrCodeRef.current = qrCode; } }, []);
页面使用代码
<div className="w-full flex flex-col gap-[16px] items-center"> {/* 二维码图片,在Chrome和Safari中都显示Logo */} <div ref={qrRef} className="rounded-[8px] border border-[4px] border-black p-[2px]" /> <button onClick={downloadQRCode}> Download as Image </button> </div>
问题原因
这个问题源于Safari处理SVG转PNG时,对外部图片的跨域逻辑和Chrome存在差异,qr-code-styling默认的download方法在Safari环境下无法正确将Logo图片嵌入到最终生成的PNG文件中。
解决方案
方案1:将Logo转为Base64格式
把你的Logo图片转换成Base64字符串,直接作为image参数传入,彻底避免跨域问题,确保Safari能正确读取并嵌入Logo:
const qrCode = new QRCodeStyling({ // ...其他配置 image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...", // 替换为你的Logo的Base64字符串 // ...其他配置 });
方案2:手动实现下载逻辑
绕过库的download方法,手动将SVG转为Canvas再导出PNG,兼容性更强:
const downloadQRCode = () => { if (!qrRef.current || !qrCodeRef.current) return; const svgElement = qrRef.current.querySelector("svg"); if (!svgElement) return; const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); if (!ctx) return; canvas.width = 160; canvas.height = 160; const img = new Image(); img.crossOrigin = "anonymous"; img.onload = () => { ctx.drawImage(img, 0, 0); const link = document.createElement("a"); link.href = canvas.toDataURL("image/png"); link.download = `${user?.username || "qrcode"}.png`; link.click(); }; img.src = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(new XMLSerializer().serializeToString(svgElement))}`; };
方案3:改用Canvas模式生成二维码
将qr-code-styling的type从svg改为canvas,直接生成Canvas格式的二维码,下载时兼容性更稳定:
const qrCode = new QRCodeStyling({ width: 160, height: 160, type: "canvas", // 替换为canvas // ...其他配置 });
内容的提问来源于stack exchange,提问作者tiennl
相关产品推荐
相关产品推荐

