Javascript 如何将内联svg(在DOM中)绘制到画布?
嗯,我需要一些关于将.svg文件/图像转换为.png文件/图像的帮助 我的页面上显示了一个.svg图像。它保存在我的服务器上(作为.png文件)。我需要按需将其转换为.png文件(单击按钮),并将.png文件保存在服务器上(我将使用.ajax请求完成此操作) 但问题是转换 我读了很多关于html5画布的东西,这可能有助于我现在需要做的事情,但我找不到任何明确的解决方案,而且,tbh,我不理解我发现的一切。。。因此,我需要一些明确的建议/帮助,告诉我如何去做 以下是“html创意”模板:Javascript 如何将内联svg(在DOM中)绘制到画布?,javascript,html,canvas,svg,png,Javascript,Html,Canvas,Svg,Png,嗯,我需要一些关于将.svg文件/图像转换为.png文件/图像的帮助 我的页面上显示了一个.svg图像。它保存在我的服务器上(作为.png文件)。我需要按需将其转换为.png文件(单击按钮),并将.png文件保存在服务器上(我将使用.ajax请求完成此操作) 但问题是转换 我读了很多关于html5画布的东西,这可能有助于我现在需要做的事情,但我找不到任何明确的解决方案,而且,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>
$(“body”)。在(“单击”,“按钮”,函数()上){
var svgText=$(“#myViewer”).outerHTML;
var myCanvas=document.getElementById(“canvas”);
var ctxt=myCanvas.getContext(“2d”);
});
然后,我需要将svg绘制到画布中,获取base64数据,并将其保存在服务器上的.png文件中。。。但是怎样?我读到很多不同的解决方案,我实际上。。。迷路的我正在做一个JSFIDLE,但我实际上。。。没有。。。感谢阅读/帮助有关内联SVG的内容,您需要:
- 将SVG字符串转换为
Blob
- 获取Blob的URL
- 创建图像元素并将URL设置为
src
- 加载时(
),您可以将SVG绘制为画布上的图像onload
- 使用
从画布获取PNG文件toDataURL()
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
});
当然,这里的console.log只是一个例子。在此处存储/传输字符串。(我还建议在方法中添加onerror
处理程序)
另外,请记住使用
宽度
和高度
属性设置画布大小,或者使用属性从JavaScript设置画布大小。我很久以前就遇到过这个问题,因为接受的答案可能会产生不良行为
@K3N解决方案几乎是正确的,但我反对使用svgElement.outerHTML
相反,人们应该更愿意这样做 此外,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())
});
'一个.svg图像[…]被保存[…]为一个.png文件'这是如何工作的?!请看一下我提供的结帐单。它应该可以解决您的问题这在这里和JSFIDLE上都是完美的。。。。但是当我尝试在我的项目中使用它时,它看起来好像绘图功能不起作用…@Julo0sS您在控制台中遇到了什么错误?是否添加了onerror处理程序?尝试插入各个阶段的console.log,并查看代码停止的位置。输出变量以查看它们是否实际包含数据或未定义。检查您是否正确获取SVG outerHTML。我的2美分。语法
self.URL | | | self.webkitURL | | | self
的含义是什么?你能解释一下这个表达式的作用吗?@K3N你如何在console.log(canvas.toDataURL())中获得canvas
代码>?此答案的问题是,只有一部分生成的图像显示为转换为png图像,而不是整个svg图像。我尝试了前面的答案,如果svg没有“xmln”属性,它将失败。@kaido的答案是一个很好的改进,并且与“格式错误”的SVG一起工作。@user305883,感谢您的反馈。只是想让您知道,
元素在附加到HTML文档时不必有xmlns
声明。所以您的SVG没有“格式错误”,只是它是一个SVG元素,而不是一个SVG文档。dataURI应该表示一个文档,因此失败。XMLSerializer()确实为我们处理转换。嘿,伙计们,很抱歉在已经回答的问题上把这个问题拖了上来。我按照这封信的回答,一切都很顺利,除了当我到达canvas.toDataURL()
时,我得到了一个SecurityError
。我正在使用此方法将Highcharts.js svg转换为png,因此我不确定CORS问题的来源(据我所知,这是CORS问题???)Highcharts svg都在浏览器中呈现。@MartinOLeary这不是CORS问题。在画布上绘制某些svg元素时,某些UAs具有安全限制。在哪个浏览器上会发生这种情况?如果IE
节点必须具有绝对设置的宽度和高度属性(而不是像%
这样的相对属性); 请注意,IE没有在指向svg文档的HTMLImages上设置宽度
或高度
(以及它们的naturalXXX
等价物):对于此浏览器,您需要自己从svg标记或in文档节点的offsetXXX
获取宽度;注意,当svg通过drawImage
绘制到画布上时,所有IE
元素时,Safari>=9确实会污染画布。