我相信我的问题的答案可以在 Is there an equivalent of canvas's toDataURL method for SVG? 中找到.有人可以确认或给我一个正确方向的指示。
如果 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>
我什至使用 node 0.4.2 和使用 cairo 库的 node-canvas 编写了一个等效程序,当使用 canvas.toDataURL() 和 SVG 图像时我得到了相同的结果。当使用 node-canvas 时,由于某种原因没有触发 img.onload 事件,如果我试图在不等待 onload 事件的情况下绘制图像,我会收到一条错误消息,指出图像尚未完成加载。 Node 程序也可以在下面找到。
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>
最佳答案
Webkit currently taints the canvas when you draw an SVG to it (due to difficult-to-track security concerns). Until FF v12 this was also the case with Firefox, but it is now fixed. You will need to use an SVG parser like CanVG for now if you need the data URL.
关于html - toDataURL 不适用于带有 SVG 图像的 html5 Canvas ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10317970/