Javascript 从canvas元素获取SVG并保存
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10273516/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get SVG from canvas element and save it
提问by kaiser
Currently I'm creating a small application for a friend, who′s starting his PhD and needs to build some network graphs. So far everything works fine using the a Force Directed graph. The graphs nodes can be moved to style the layout.
目前我正在为一个朋友创建一个小应用程序,他正在攻读博士学位,需要构建一些网络图。到目前为止,使用力有向图一切正常。可以移动图形节点以设置布局样式。
The thing I can't get my head around is:
我无法理解的是:
?how to extract the data from the canvas and save it to a SVG file?.
?如何从画布中提取数据并将其保存到 SVG 文件中?.
What I tried:
我试过的:
I already tried accessing the image Data from the console with
我已经尝试从控制台访问图像数据
var app.canvas = document.getElementById( 'graph-canvas' )
.getContext( '2d' )
.getImageData( 0, 0, 200, 200 );
and got an (object) ImageData
in return. Now I can access the ↑ shown canvas data with app.canvas.data
. (When I try too look up the values, the browser starts hanging and asks if the script should be stopped - Chrome & FF latest).
并得到了(object) ImageData
回报。现在我可以访问 ↑ 显示的画布数据app.canvas.data
。(当我尝试查找值时,浏览器开始挂起并询问是否应停止脚本 - Chrome 和 FF 最新版本)。
How would I go from here to get the SVG drawn and then saved by the click of a button?
我将如何从这里开始绘制 SVG,然后通过单击按钮保存?
EDIT:
编辑:
So far I found out how to draw the SVG and add an image/png
element to it. How ever, it′s not displaying.
到目前为止,我发现了如何绘制 SVG 并向其添加image/png
元素。但是,它没有显示。
// Add the test SVG el:
var svg = document.createElementNS( "http://www.w3.org/2000/svg", "svg" );
svg.setAttribute( 'style', 'border: 1px solid black;' )
.setAttribute( 'width', '600' )
.setAttribute( 'height', '400' )
.setAttributeNS(
'http://www.w3.org/2000/xmlns/',
'xmlns:xlink',
'http://www.w3.org/1999/xlink'
);
// Call
importCanvas( document.getElementById( 'infovis-canvas' ), svg );
// Function: Add data to SVG
function importCanvas( sourceCanvas, targetSVG )
{
// get base64 encoded png data url from Canvas
var img_dataurl = sourceCanvas.toDataURL( "image/png" );
var svg_img = document.createElementNS(
"http://www.w3.org/2000/svg",
"image"
);
svg_img.setAttributeNS(
'http://www.w3.org/1999/xlink',
'xlink:href',
img_dataurl
);
jQuery( targetSVG.appendChild( svg_img ) )
.appendTo( '#graph-container' );
console.log( 'done' ); // Log & confirm
}
And finally the...
最后...
// ...resulting SVG element containing the image element
<svg style="border: 1px solid black;" width="600" height="400" xlink="http://www.w3.org/1999/xlink"><image href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABQAAA(...)
The UI works with jQuery UI, jQuery and the The Jit/InfoVIZlibrary, so those are available.
UI 与 jQuery UI、jQuery 和Jit/InfoVIZ库一起使用,因此这些都是可用的。
回答by Erik Dahlstr?m
If you want to preserve it as a vector graphic instead of as a raster, you can try one of the libraries that translate the canvas API operations to svg.
如果您想将其保留为矢量图形而不是光栅,您可以尝试将画布 API 操作转换为 svg 的库之一。
For SVGKit:
对于SVGKit:
var svgkitContext = new SVGCanvas(150,150);
function draw(ctx) {
// ... normal canvas drawing commands go here ...
}
// draw to SVGKit canvas (svg) instead of canvasElement.getContext("2d")
draw(svgkitContext);
Full running exampleof the above.
上面的完整运行示例。
For canvas-svg:
对于画布 svg:
var canvasSVGContext = new CanvasSVG.Deferred();
canvasSVGContext.wrapCanvas(document.querySelector("canvas"));
var canvasContext = document.querySelector("canvas").getContext("2d");
function draw(ctx) {
// ... normal canvas drawing commands go here ...
}
// draw to html5 canvas and record as svg at the same time
draw(canvasContext);
// append the svg result
var svg = document.appendChild(canvasContext.getSVG());
Full running exampleof the above.
上面的完整运行示例。
For generating svg instead:
用于生成 svg:
Another option is of course to make the graph as an svg in the first place, d3.jsis a javascript library that makes it easy to do this, see e.g this exampleof a force directed graph.
另一种选择当然是首先将图形制作为 svg,d3.js是一个 javascript 库,可以轻松做到这一点,例如,请参阅此力有向图示例。
回答by mihai
If you're limited to ImageData
you're out of luck, because that's just a mere pixel array (see reference). You can't obtain a meaningful SVG image from there. You can probably pull off a .png
representation...but that's a static image with no interaction.
如果您仅限ImageData
于此,那您就不走运了,因为那只是一个像素阵列(请参阅参考资料)。您无法从那里获得有意义的 SVG 图像。您可能可以完成一个.png
表示......但这是一个没有交互的静态图像。
If you're going to do some sort of canvas to SVG export, it's important how you're doing the canvas drawing. The best approach would be to use a library that maintains a canvas scene graph.
如果您要为 SVG 导出做某种画布,那么画布绘图的方式很重要。最好的方法是使用维护画布场景图的库。
Fabric.jsseems to be a good choice. You can do the drawing with canvas and then call canvas.toSVG()
and get your svg image.
Fabric.js似乎是一个不错的选择。您可以使用画布进行绘图,然后调用canvas.toSVG()
并获取您的 svg 图像。