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

在服务端通过Javascript/PHP将带Logo的二维码保存为PNG/JPEG

问题:生成内嵌Logo的PNG/JPEG二维码无法正常打开

开发小型项目时需要生成带内嵌Logo的二维码,并保存为PNG或JPEG格式。当前代码在使用SVG格式时运行正常,但改为PNG/JPEG格式后,文件虽能保存却无法打开,系统提示格式不支持。

原前端HTML代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>QR Code Styling</title>
  <script type="text/javascript" src="https://unpkg.com/qr-code-styling@1.5.0/lib/qr-code-styling.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
</head>

<body>
  <div id="canvas"></div>
  <script type="text/javascript">

    const qrCode = new QRCodeStyling({
      width: 300,
      height: 300,
      type: "svg",
      data: "https://www.facebook.com/",
      image: "https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg",
      dotsOptions: {
        color: "#4267b2",
        type: "rounded"
      },
      backgroundOptions: {
        color: "#e9ebee",
      },
      imageOptions: {
        crossOrigin: "anonymous",
        margin: 20
      }
    });

    var svgBlob = qrCode.getRawData('jpeg');
    svgBlob.then(value => value.text().then(value => sendAjax(value)));

    function sendAjax(svgString) {
      $.ajax('saveqr.php', {
        'data': svgString, //canvas.innerHTML,
        'type': 'POST',
        'processData': false,
        'contentType': 'image/jpg'
      });
    }
    qrCode.append(document.getElementById("canvas"));
    // qrCode.download({ name: "qr", extension: "svg" });
  </script>
</body>

</html>

原后端saveqr.php代码

<?php 
$svg = file_get_contents('php://input');
$myfile = fopen("testfile.jpeg", "w");
fwrite($myfile, $svg);
?>

问题根源

  1. 生成位图二维码时,QRCodeStyling的type参数仍设为svg,无法生成正确的二进制位图数据
  2. 读取Blob时错误使用text()方法,将二进制图像数据转成字符串导致数据损坏
  3. PHP写入文件时使用文本模式,破坏了二进制图像的结构

修复后的代码

前端HTML代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>QR Code Styling</title>
  <script type="text/javascript" src="https://unpkg.com/qr-code-styling@1.5.0/lib/qr-code-styling.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
</head>

<body>
  <div id="canvas"></div>
  <script type="text/javascript">

    const qrCode = new QRCodeStyling({
      width: 300,
      height: 300,
      type: "canvas", // 改为canvas类型以生成位图格式
      data: "https://www.facebook.com/",
      image: "https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg",
      dotsOptions: {
        color: "#4267b2",
        type: "rounded"
      },
      backgroundOptions: {
        color: "#e9ebee",
      },
      imageOptions: {
        crossOrigin: "anonymous",
        margin: 20
      }
    });

    // 直接获取Blob并发送二进制数据,避免转文本损坏
    qrCode.getRawData('jpeg').then(blob => {
      sendAjax(blob);
    });

    function sendAjax(blob) {
      $.ajax('saveqr.php', {
        data: blob,
        type: 'POST',
        processData: false,
        contentType: 'image/jpeg' // 修正contentType为标准的image/jpeg
      });
    }
    qrCode.append(document.getElementById("canvas"));
  </script>
</body>

</html>

后端saveqr.php代码

<?php 
// 读取二进制输入数据
$imageData = file_get_contents('php://input');
// 以二进制写入模式打开文件,避免损坏图像数据
$myfile = fopen("testfile.jpeg", "wb");
fwrite($myfile, $imageData);
fclose($myfile); // 关闭文件句柄,确保数据写入完成
?>

关键修改说明

  • QRCodeStyling类型切换:将type从svg改为canvas,让库基于Canvas生成位图,才能输出PNG/JPEG格式的二进制数据。
  • Blob处理优化:直接传递Blob对象给AJAX,跳过文本转换步骤,保证二进制数据完整性。
  • PHP写入模式修正:使用wb二进制写入模式,避免文本模式下的编码转换破坏图像结构。

内容的提问来源于stack exchange,提问作者Nitin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 06:34:55