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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 04:45:44