toDataURL不适用于具有SVG图像的html5canvas

我相信我的问题的答案可以在SVG的canvas的toDataURL方法有相当的? 。 有人可以确认或给我一个正确的方向指针。

如果canvas包含Chrome和/或Safari上的SVG,则无法使用canvas.toDataURL()生成正确的图像。 下面的代码说明了这个问题。

<!DOCTYPE html> <html> <head> <script src="http://code.jquery.com/jquery-latest.js"></script> <script> $(document).ready(function () { var __readLocalXml = function(file) { xmlHttp = new XMLHttpRequest(); xmlHttp.open("GET",file,false); xmlHttp.send(); return xmlHttp.responseXML; }; var __drawSVG = function(context, sourceSVG, x, y){ var svg_xml = (new XMLSerializer()).serializeToString(sourceSVG); var img = new Image(); img.src=""; var myFunction = function() { context.drawImage(img, x, y); } img.addEventListener('load', myFunction, false); img.src = "data:image/svg+xml;base64,"+btoa(svg_xml); }; var settings = { //White King //Chess_klt45.svg //<http://en.wikipedia.org/wiki/File:Chess_klt45.svg> 'whiteKingSVG' : function() { return __readLocalXml("svg/Chess_klt45.svg") } } var canvas = document.createElement('canvas'); var cw = canvas.width = 45; var ch = canvas.height = 45; var context = canvas.getContext('2d'); context.fillStyle = '#FFFFCC'; context.fillRect(0, 0, ch, cw); __drawSVG(context, settings.whiteKingSVG(),0,0); $('#withCanvas').after(canvas); $('#withToDataUrl').after('<img src="' + canvas.toDataURL() + '" />'); }); </script> </head> <body> <h1>Works</h1> <div id="withCanvas"></div> <hr> <h1>Does not Work</h1> <div id="withToDataUrl"></div> </body> </html> 

我甚至使用节点0.4.2和使用cairo库的node-canvas编写了一个等效的程序,并且在使用canvas.toDataURL()和SVG图像时得到了相同的结果。 当使用node-canvas时,由于某种原因,img.onload事件没有被触发,如果我试图绘制图像而不等待onload事件,我得到一个错误,说图像没有完成加载。 节点程序也可以在下面find。

 var Canvas = require('canvas'); var __readFileNodeSync=function(file){ var fs = require('fs'); try { return fs.readFileSync(file, 'ascii'); } catch (err) { console.error("There was an error opening the file:"); console.log(err); } } var __loadXml_xmldom=function(file){ var DOMParser = require("xmldom").DOMParser; var xml=__readFileNodeSync(file) return new DOMParser().parseFromString(xml) } var __drawSVG = function(context, sourceSVG, x, y){ var btoa = require('btoa'); var XMLSerializer = require("xmldom").XMLSerializer; var svg_xml = new XMLSerializer().serializeToString(sourceSVG); var img = new Canvas.Image; img.onload = function(){ context.drawImage(img, x, y); } img.src = "data:image/svg+xml;base64,"+btoa(svg_xml); }; var settings = { //White King //Chess_klt45.svg //<http://en.wikipedia.org/wiki/File:Chess_klt45.svg> 'whiteKingSVG' : function() { return __loadXml_xmldom("../svg/Chess_klt45.svg") } } var canvas = new Canvas(); var cw = canvas.width = 45; var ch = canvas.height = 45; var context = canvas.getContext('2d'); context.fillStyle = '#FFFFCC'; context.fillRect(0, 0, ch, cw); __drawSVG(context, settings.whiteKingSVG(),0,0); console.log("<html>"); console.log("<head>"); console.log("</head>"); console.log("<body>"); console.log('<img src="'+canvas.toDataURL() + '" />'); console.log("</body>"); console.log("</html>"); 

编辑我能解决我的问题,感谢@ Phrogz的评论
下面是解决问题的代码

 <!DOCTYPE html> <html> <head> <script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/rgbcolor.js"></script> <script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/canvg.js"></script> <script src="http://code.jquery.com/jquery-latest.js"></script> <script> $(document).ready(function () { var settings = { //White King //Chess_klt45.svg //<http://en.wikipedia.org/wiki/File:Chess_klt45.svg> 'whiteKingSVG' : "svg/Chess_klt45.svg" } var canvas = document.createElement('canvas'); var cw = canvas.width = 45; var ch = canvas.height = 45; var context = canvas.getContext('2d'); context.fillStyle = '#FFFFCC'; context.fillRect(0, 0, ch, cw); canvg(canvas, settings.whiteKingSVG, { ignoreMouse: true, ignoreAnimation: true, ignoreDimensions: true, ignoreClear: true, offsetX: 0, offsetY: 0 }); $('#withCanvas').after(canvas); $('#withToDataUrl').after('<img alt="whiteKing.png" src="' + canvas.toDataURL("image/png") + '" />'); }); </script> </head> <body> <h1>Works</h1> <div id="withCanvas"></div> <hr> <h1>Works! (using canvg)</h1> <div id="withToDataUrl"></div> </body> </html> 

当你绘制一个SVG的时候,Webkit现在会污染canvas(由于难以跟踪的安全问题)。 在FF v12之前,Firefox也是如此,但现在已经修复了。 如果您需要数据URL,您现在需要使用像CanVG这样的SVGparsing器。