如何将内联 svg(在 DOM 中)绘制到画布

How to draw an inline svg (in DOM) to a canvas?

本文关键字:绘制 DOM svg      更新时间:2023-09-26

好吧,我需要一些关于将.svg文件/图像转换为.png文件/图像的帮助......

我的页面上显示了一张.svg图像。它保存在我的服务器上(作为.png文件(。我需要根据需要将其转换为.png文件(单击按钮(并将.png文件保存在服务器上(我将使用 .ajax 请求执行此操作(。

但问题是转换。

我读了很多关于 html5 Canvas 的东西,它可能有助于做我现在需要做的事情,但我找不到任何明确的解决方案来解决我的问题,而且,tbh,我不明白我发现的一切......所以我需要一些关于我必须这样做的方式的明确建议/帮助。

这是"html 想法"模板:

<html>
    <body>
        <svg id="mySvg" width="300px" height="300px">
            <!-- my svg data -->
        </svg>
        <label id="button">Click to convert</label>
        <canvas id="myCanvas"></canvas>
    </body>
</html>

和一些 js :

<script>
    $("body").on("click","#button",function(){
        var svgText = $("#myViewer").outerHTML;
        var myCanvas = document.getElementById("canvas");
        var ctxt = myCanvas.getContext("2d");
    });
</script>

然后,我需要将 svg 绘制到 Canvas 中,取回 base64 数据,并将其保存在服务器上的.png文件中......但。。。如何?我读了很多不同的解决方案,我实际上是......失去。。。我正在研究一个jsfiddle,但我实际上...无处。。。http://jsfiddle.net/xfh7nctk/6/......感谢您的阅读/帮助

对于内联 SVG,您需要:

  • 将 SVG 字符串转换为Blob
  • 获取 Blob 的网址
  • 创建图像元素并将 URL 设置为src
  • 加载(onload(时,您可以将SVG绘制为画布上的图像
  • 使用toDataURL()从画布获取 PNG 文件。

例如:

function drawInlineSVG(ctx, rawSVG, callback) {
    var svg = new Blob([rawSVG], {type:"image/svg+xml;charset=utf-8"}),
        domURL = self.URL || self.webkitURL || self,
        url = domURL.createObjectURL(svg),
        img = new Image;
    img.onload = function () {
        ctx.drawImage(this, 0, 0);     
        domURL.revokeObjectURL(url);
        callback(this);
    };
    img.src = url;
}
// usage:
drawInlineSVG(ctxt, svgText, function() {
    console.log(canvas.toDataURL());  // -> PNG data-uri
});

当然,控制台.log这里只是一个例子。在此处存储/传输字符串。(我还建议在方法中添加一个onerror处理程序(。

还要记住使用 widthheight 属性设置画布大小,或者使用属性从 JavaScript 设置画布大小。

我很久以后才从这个问题中提出其他一些问题,因为接受的答案可能会产生不良行为。

@K3N解决方案几乎是正确的,但我反对使用svgElement.outerHTML.
相反,人们应该更喜欢new XMLSerializer().serializeToString(svgElement) .

此外,不需要使用 blob 和 URL API,简单的 dataURI 在浏览器之间具有更高的兼容性。

所以一个完整的版本是:

function drawInlineSVG(svgElement, ctx, callback) {
  var svgURL = new XMLSerializer().serializeToString(svgElement);
  var img = new Image();
  img.onload = function() {
    ctx.drawImage(this, 0, 0);
    callback();
  }
  img.src = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(svgURL);
}
// usage:
drawInlineSVG(document.querySelector('svg'), ctxt, function() {
  console.log(canvas.toDataURL())
});