【问题标题】:Downloading Canvas as JPG/PNG returns blank image以 JPG/PNG 格式下载 Canvas 会返回空白图像
【发布时间】:2021-08-30 17:15:37
【问题描述】:

所以,我正在使用 canvg 和将 svg 文件转换为 jpg/png 的函数只是下载并忽略 svg 块元素的 id,所以我得到了空白图像,可能有什么问题?也许 Vue 不支持使用画布将 SVG 转换为 jpg/png。 这是javascript:

import canvg from "canvg";

 function SVG2PNG(svg, callback) {
  var canvas = document.createElement("canvas");
  var w = 800;
  var h = 400;
  canvas.width = w;
  canvas.height = h; // Create a Canvas element.
  var ctx =  canvas.getContext("2d"); // For Canvas returns 2D graphic.
  debugger;
  var data = svg.outerHTML; // Get SVG element as HTML code.
  canvg.from(canvas, data); // Render SVG on Canvas.
  callback(canvas); // Execute callback function.
}

function generateLink(fileName, data) {
  var link = document.createElement("a");
  link.download = fileName;
  link.href = data;
  return link;
}

export default {
  methods: {
    tipka() {
        debugger;
      var element = document.getElementById("svg"); // Get SVG element.
      SVG2PNG(element, function (canvas) {
        // Arguments: SVG element, callback function.
        var base64 = canvas.toDataURL("image/png"); // toDataURL return DataURI as Base64 format.
        generateLink("SVG2PNG-01.png", base64).click(); // Trigger the Link is made by Link Generator and download.
      });
    },
  },
};

这里是 svg 标签的结尾: 这是 svg 标签的开始:

【问题讨论】:

  • (从一个答案到另一个问题进一步澄清问题)根据我的实验,看起来次要问题可能涉及 XML 命名空间。你能发布 opening <svg> 标签吗?它的属性在这里可能至关重要。
  • 当然,我添加了开头svg,我也认为可能是xml问题。
  • 这是在svg标签中转换的形状的完整代码(它可能对更好的测试有用):privatebin.net/…

标签: vue.js svg canvas canvg


【解决方案1】:

根据documentation for Canvg.from,您需要将绘图上下文传递给它,而不是画布本身。所以改变这一行:

canvg.from(canvas, data); // Render SVG on Canvas.

到:

canvg.from(ctx, data); // Render SVG on Canvas.

根据this answer,您还需要将<svg> 上的viewBox 属性替换为widthheight 属性,例如:

<svg class="shape" version="1.1" id="svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="400" height="400" style="enable-background:new 0 0 400 400;" xml:space="preserve">

然后,您实际上可以完全绕过canvg,使用这样重写的函数:

function SVG2PNG(svg, callback) {
    var canvas = document.createElement("canvas");
    canvas.width = 400;
    canvas.height = 400; // Create a Canvas element.
    var ctx = canvas.getContext("2d"); // For Canvas returns 2D graphic.
    var svgString = svg.outerHTML;
    var img = new Image();
    img.addEventListener('load', () => {
        ctx.drawImage(img, 0, 0, 400, 400);
        callback(canvas.toDataURL("image/png")); // toDataURL return DataURI as Base64 format.
    });
    img.src = 'data:image/svg+xml,' + svgString;
}

(请注意,它现在返回的是数据 URL,而不是画布。)

【讨论】:

  • 我试过了,还是一样(下载空白图片),这可能是vue的问题吗?就好像 svg 元素被忽略了...
  • 如果在这段代码运行之前 SVG 确实存在于您的页面上,那么 Vue 是否会与此有任何关系。 data 变量在SVG2PNG 中初始化后包含什么?
  • 可能 canvas 不支持 svg 块标签。在方法变量数据中初始化后,它包含我要转入图像的整个 svg 代码。
  • 好吧,我不确定canvg 库的限制,但如果您已经拥有整个 SVG,您应该能够将其加载到 HTMLImageElement 并直接传递给 @987654323 @ 不需要任何特殊的库。
  • 你能在你的答案中显示这个吗?我将不胜感激。
猜你喜欢
  • 2021-03-25
  • 2013-05-10
  • 2012-08-13
  • 1970-01-01
  • 1970-01-01
  • 2019-08-25
  • 2015-09-20
  • 2023-03-05
相关资源
最近更新 更多