我正在尝试将svg图像加载到画布中以进行像素操作 对于svg
,我需要toDataURL
或getImageData
等方法
Chrome浏览器上的我可以尝试通过图片和画布
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 :))
但是我遇到了安全错误。 还有别的吗?
以下是问题http://clstff.appspot.com/gist/462846的实时演示(您可以查看来源)
答案 0 :(得分:8)
var dataUrl = 'data:image/svg+xml,'+encodeURIComponent(svgString);
答案 1 :(得分:5)
来自:http://www.svgopen.org/2009/papers/12-Using_Canvas_in_SVG/#d4e105
您无法使用SVG的原因 图像元素作为源的 drawImage方法很简单,但是 痛苦:当前的画布 规范(尚未)允许 引用SVGImageElement作为源 对于drawImage而言只能应付 HTMLImageElement,HTMLCanvasElement 和HTMLVideoelement。这个 希望是短暂的到来 在此过程中解决 定义“HTML5中的SVG”行为和 可以扩展到允许 SVGSVGElement也是如此。 xhtml:img 清单3中的元素使用 可见性:隐藏,因为我们不想要它 干扰其可见副本 画布。
答案 2 :(得分:1)
是的,你不能直接这样做,但你可以使用canvg,我的意思是,将SVG绘制到Canvas,并从Canvas获取数据网址。它不是没有错误,特别是对于复杂的渐变处理,但我有一些积极的经验。
答案 3 :(得分:1)
首先下载一个js库svg_todataurl.js并将其包含在内
然后只需粘贴此代码
var SVGtopngDataURL = document.getElementById("svg_element_id").toDataURL("image/png");
答案 4 :(得分:0)
用代码说明Hubert OG的答案;首先有2条评论。
首先(谢谢罗伯特·朗森(Robert Longson),它可能在没有encodeURIComponent的情况下也可以工作,但是最好包括它(例如,如果您有类似fill="url(#pattern)"
之类的编码URIComponent,则必须使用#字符)>
第二,SVG名称空间不是不是可选的,但是它可能不包含在svgElt.outerHTML
中。特别是,如果您是通过createElementNS
创建的svg节点,就像这样
svgElt = document.createElementNS("http://www.w3.org/2000/svg", 'svg')
然后随后对svgElt.outerHTML
的调用将不会包含名称空间属性,除非您稍后以某种方式包括名称空间属性,否则这将导致代码无法正常工作
var imgEnc = new Image();
var imgEncNS = new Image();
var prefix = 'data:image/svg+xml,';
var svgOpen = '<svg width="200" height="30">';
var svgClose = '</svg>';
var svgOpenNS = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="30">';
var rect = '<rect width="200" height="30" fill="black"/>';
var html = svgOpen + rect + svgClose;
var htmlNS = svgOpenNS + rect + svgClose;
var htmlEnc = window.encodeURIComponent(html);
var htmlEncNS = window.encodeURIComponent(htmlNS);
imgEnc.src = prefix + htmlEnc;
imgEncNS.src = prefix + htmlEncNS;
function T(txt){
document.body.appendChild(document.createTextNode(txt));
}
function HR(){ document.body.appendChild(document.createElement('hr')); }
function BR(){ document.body.appendChild(document.createElement('br')); }
function A(arg){ document.body.appendChild(arg); }
T('without namespace'); BR(); A(imgEnc); HR();
T('with namespace'); BR(); A(imgEncNS);
您可以在我对this question的回答中使用函数outerXHTML
来解决缺少的名称空间问题
或这样
function imgFromSVGnode(node){
function setNS(elt, parentNS){
var namespace = elt.namespaceURI;
if (namespace!==parentNS){
elt.setAttribute('xmlns', namespace);
}
for (var i=0; i<elt.childNodes.length; i++){
setNS(elt.childNodes[i], namespace);
}
}
setNS(node, null);
var html = node.outerHTML;
var dataURL = 'data:image/svg+xml,' + window.encodeURIComponent(html);
var img = new Image();
img.src = dataURL;
return img;
};