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

如何在JavaScript服务端将API获取的SVG二维码旋转45度

解决方案

问题分析

核心问题是svgToImg函数用法错误,同时画布旋转逻辑存在疏漏——原代码先绘制未旋转的图片,再旋转画布重绘,导致两张图重叠。另外,直接操作SVG文本实现旋转比转PNG再处理更高效。


方案一:修正PNG转换与旋转逻辑

用你已引入的svg2img替代svgToImg,调整画布旋转的正确步骤:

const { createCanvas } = require("canvas");
const svg2img = require("svg2img");
const axios = require("axios");

async function processQrCode(qrCodeData) {
  const qrCodeSvgUrl = qrCodeData.data.qr_code;
  // 获取SVG文本
  const svgResponse = await axios.get(qrCodeSvgUrl, { responseType: "text" });
  const qrCodeSvg = svgResponse.data;

  // 将SVG转为PNG Buffer
  const pngBuffer = await new Promise((resolve, reject) => {
    svg2img(qrCodeSvg, { width: 200, height: 200 }, (error, buffer) => {
      if (error) reject(error);
      else resolve(buffer);
    });
  });

  // 创建画布并处理旋转
  const canvas = createCanvas(283, 283); // 旋转后正方形变菱形,扩大画布避免裁剪
  const ctx = canvas.getContext("2d");
  
  // 移动原点到画布中心,旋转45度
  ctx.translate(canvas.width / 2, canvas.height / 2);
  ctx.rotate((45 * Math.PI) / 180);
  
  // 绘制图片到旋转后的画布(中心对齐)
  const img = new canvas.Image();
  img.src = pngBuffer;
  ctx.drawImage(img, -img.width / 2, -img.height / 2);

  // 获取旋转后的PNG Buffer
  const rotatedPngBuffer = canvas.toBuffer();
  qrCodeData.data.qr_code = rotatedPngBuffer;
  
  // 后续存入数据库逻辑...
}

关键修正点:

  • 将svg2img的回调转为Promise,适配async/await逻辑
  • 扩大画布尺寸:正方形旋转45度后对角线为原边长的√2倍,200*1.414≈283,防止二维码被裁剪
  • 调整旋转顺序:先平移原点、旋转画布,再绘制图片,确保只渲染旋转后的内容

方案二:直接修改SVG文本实现旋转(更高效)

无需转换格式,直接给SVG根元素添加transform属性实现旋转,处理速度更快:

const axios = require("axios");

async function processQrCode(qrCodeData) {
  const qrCodeSvgUrl = qrCodeData.data.qr_code;
  const svgResponse = await axios.get(qrCodeSvgUrl, { responseType: "text" });
  let qrCodeSvg = svgResponse.data;

  // 给SVG根元素添加旋转属性(以中心为原点旋转45度)
  const svgWidth = 200; // 可从SVG文本中提取实际宽高
  const svgHeight = 200;
  const transform = `rotate(45 ${svgWidth/2} ${svgHeight/2})`;
  
  // 替换svg标签,插入transform属性
  qrCodeSvg = qrCodeSvg.replace(/<svg/, `<svg transform="${transform}"`);

  // 若需转PNG,取消下方注释
  // const rotatedPngBuffer = await new Promise((resolve, reject) => {
  //   svg2img(qrCodeSvg, { width: svgWidth, height: svgHeight }, (error, buffer) => {
  //     error ? reject(error) : resolve(buffer);
  //   });
  // });
  // qrCodeData.data.qr_code = rotatedPngBuffer;

  // 直接存储修改后的SVG文本
  qrCodeData.data.qr_code = qrCodeSvg;
  
  // 后续存入数据库逻辑...
}

优势:

  • 避免格式转换的性能损耗
  • 保留SVG的矢量特性(若数据库支持存储SVG文本)
  • 代码更简洁,无需依赖canvas库

内容的提问来源于stack exchange,提问作者program.exe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 12:50:07