如何使用html5 canvas/javascript/jquery将svg转换为png并保存在服务器上

Jul*_*0sS 27 html javascript svg png canvas

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

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

但问题是转换.

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

这是"html idea"模板:

<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>
Run Code Online (Sandbox Code Playgroud)

和一些js:

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

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

小智 42

对于内联SVG,您需要:

  • 将SVG字符串转换为a Blob
  • 获取Blob的URL
  • 创建一个图像元素并将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
});
Run Code Online (Sandbox Code Playgroud)

当然,这里的console.log就是例如.在此处存储/传输字符串.(我还建议onerror在方法中添加一个处理程序).

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

  • @ K3N如何在console.log(canvas.toDataURL());中获取`canvas`? (3认同)

Kai*_*ido 27

我很久以后就提出了一个问题,因为接受的答案可能会产生不良行为.

@ 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())})
Run Code Online (Sandbox Code Playgroud)

  • 我尝试了上一个答案,如果 SVG 没有 'xmln' 属性,它将失败。@Kaiido 的答案是一个很好的改进,并且也适用于“格式错误”的 SVG。 (2认同)
  • @ user305883,感谢您的反馈.只是为了让你知道`<svg>`元素在附加到HTML文档时不必具有`xmlns`声明.所以你的SVG没有"格式错误",只是它是一个svg元素,而不是一个svg文件.dataURI应该代表一个文档,因此失败.XMLSerializer()确实为我们处理转换. (2认同)
  • @TanyaGupta,请注意根`&lt;svg&gt;`节点必须具有绝对设置的`width`和`height`属性(而不是像`%`这样的相对属性);请注意,IE 没有在指向 svg 文档的 HTMLImage 上设置“宽度”或“高度”(以及它们的“naturalXXX”等效项):对于此浏览器,您需要自己获取宽度,无论是从svg 标记,来自文档节点的 `offsetXXX` ;请注意,当通过“drawImage”将 svg 绘制到画布上时,所有 IE &lt; Edge 都会污染画布;当在画布上绘制“&lt;foreignObject&gt;”元素时,Safari &gt;= 9 确实会污染画布。 (2认同)