Javascript 是否有帆布的等价物';SVG的toDataURL方法是什么?

Javascript 是否有帆布的等价物';SVG的toDataURL方法是什么?,javascript,html,canvas,svg,Javascript,Html,Canvas,Svg,我正在尝试将svg图像加载到画布中进行像素操作 我需要一个类似于svg的toDataURL或getImageData的方法 在Chrome/Safari上,我可以尝试通过图像和画布进行操作 var img = new Image() img.onload = function(){ ctx.drawImage(img,0,0) //this correctly draws the svg image to the canvas! however... var dataURL = canv

我正在尝试将svg图像加载到画布中进行像素操作 我需要一个类似于svg的
toDataURL
getImageData
的方法

在Chrome/Safari上,我可以尝试通过图像和画布进行操作

var img = new Image()
img.onload = function(){
  ctx.drawImage(img,0,0) //this correctly draws the svg image to the canvas! however...
  var dataURL = canvas.toDataURL(); //SECURITY_ERR: DOM Exception 18
  var data = ctx.getImageData(0,0,img.width, img.height).data //also SECURITY_ERR: DOM Exception 18
  }
  img.src = "image.svg" //that is an svg file. (same domain as html file :))
但我有安全错误。 还有别的办法吗

以下是问题的现场演示(您可以查看源代码)

来自:

无法使用SVG的原因 图像元素作为 drawImage方法很简单,但是 痛苦:当前画布 规范(尚未)允许 引用SVGImageElement作为源 对于drawImage,只能处理 HTMLImageElement,HTMLCanvasElement 和HTMLVideoelement。这 希望不久的将来会很好 在审查过程中处理 定义“HTML5中的SVG”行为和 可以扩展到允许 SVGSVGElement也是如此。xhtml:img 清单3中的元素使用 可见性:隐藏,因为我们不需要它 干扰其在上的可见副本 画布


是的,您不能直接这样做,但您可以使用它,我的意思是,将SVG绘制到画布,并从画布获取数据url。它并非没有bug,特别是对于复杂的渐变处理,但我对它有一些积极的经验。

首先下载一个js库svg_todataurl.js并将其包括在内

var dataUrl = 'data:image/svg+xml,'+encodeURIComponent(svgString);
然后粘贴这个代码

var SVGtopngDataURL = document.getElementById("svg_element_id").toDataURL("image/png");

用代码说明休伯特·奥格的答案;先说两句

首先(谢谢你,Robert Longson),它可能在没有encodeURIComponent的情况下工作,但最好包含它(例如,如果您有类似于
fill=“url(#pattern)”
的内容,则encodeURIComponent是必需的,因为#字符)

其次,SVG名称空间不是可选的,但它可能不包括在
svgElt.outerHTML
中。特别是,如果您已经通过
createElements
创建了svg节点,如下所示

svgElt = document.createElementNS("http://www.w3.org/2000/svg", 'svg')
然后对
svgElt.outerHTML
的后续调用将不包含名称空间属性,这将导致代码无法工作,除非稍后以某种方式包含名称空间属性

var imgEnc=new Image();
var imgEncNS=新图像();
变量前缀='data:image/svg+xml';
var svgOpen='';
var svgClose='';
var svgOpenNS='';
var rect='';
var html=svgOpen+rect+svgClose;
var htmlNS=svgOpenNS+rect+svgClose;
var htmlEnc=window.encodeURIComponent(html);
var htmlEncNS=window.encodeURIComponent(htmlNS);
imgEnc.src=前缀+htmlEnc;
imgEncNS.src=前缀+htmlEncNS;
函数T(txt){
document.body.appendChild(document.createTextNode(txt));
}
函数HR(){document.body.appendChild(document.createElement('HR');}
函数BR(){document.body.appendChild(document.createElement('BR'));}
函数A(arg){document.body.appendChild(arg);}
T('无名称空间');BR();A(紧急情况);HR();

T('with namespace');BR();A(紧急情况)SVG图像是否来自不同的域?如果是,则不能调用
toDataURL
getImageData
,因为画布不再是“源干净”的。它来自同一个域。我甚至试过做
img.src=“data:image/svg+xml;base64,…”
,但也没用这似乎是Webkit中的一个bug:我查看了这个bug。它说问题出在
drawImage
上。对我来说,
drawImage
很有效。在我绘制图像后,
toDataURL
getImageData
不起作用。您是否尝试过使用fabric.js将SVG加载到画布上,然后获取dataurl图像?svgString的意思是?var svgString=document.getElementById(“SVG\u element\u id”)。outerHTML@Eugenio:如果这不起作用,请执行var svgString=outerXHTML(document.getElementById(“svg_element_id”))和我的答案中的outerXHTML函数
.outerHTML
如果以编程方式创建节点,则缺少namespace属性。您回答的问题是由于canvas API的早期实现引起的,当时svg图像尚未被接受为源图像。今天没有任何人会面临此问题的真正原因。您可能正在寻找替代方案。