Firefox错误使用drawImage将SVG图像渲染到HTML5画布

Ane*_*esh 13 javascript firefox base64 svg html5-canvas

我正在尝试使用画布将外部svg图标转换为base64 png.它适用于除Firefox之外的所有浏览器,它会引发错误"NS_ERROR_NOT_AVAILABLE".

        var img = new Image();
        img.src = "icon.svg";

        img.onload = function() {
            var canvas = document.createElement("canvas");              
            canvas.width = this.width;
            canvas.height = this.height;
            var ctx = canvas.getContext("2d");
            ctx.drawImage(this, 0, 0);
            var dataURL = canvas.toDataURL("image/png");
            return dataURL;
        };
Run Code Online (Sandbox Code Playgroud)

有人可以帮我吗?提前致谢.

Rob*_*son 29

Firefox不支持将SVG图像绘制到画布,除非svg文件在根<svg>元素上具有width/height属性,并且这些width/height属性不是百分比.这是一个长期存在的错误.

您需要编辑icon.svg文件,使其符合上述条件.


小智 6

如前所述,这是一个未解决的错误,是由于 Firefox 在绘制到画布时接受的 SVG 大小规范受到限制而导致的。有一个解决方法。

Firefox 需要 SVG 本身具有明确的宽度和高度属性。我们可以通过获取 XML 格式的 SVG 并对其进行修改来添加这些内容。

var img = new Image();
var src = "icon.svg";

// request the XML of your svg file
var request = new XMLHttpRequest();
request.open('GET', src, true)

request.onload = function() {
    // once the request returns, parse the response and get the SVG
    var parser = new DOMParser();
    var result = parser.parseFromString(request.responseText, 'text/xml');
    var inlineSVG = result.getElementsByTagName("svg")[0];
    
    // add the attributes Firefox needs. These should be absolute values, not relative
    inlineSVG.setAttribute('width', '48px');
    inlineSVG.setAttribute('height', '48px');
    
    // convert the SVG to a data uri
    var svg64 = btoa(new XMLSerializer().serializeToString(inlineSVG));
    var image64 = 'data:image/svg+xml;base64,' + svg64;
    
    // set that as your image source
    img.src = img64;

    // do your canvas work
    img.onload = function() {
        var canvas = document.createElement("canvas");              
        canvas.width = this.width;
        canvas.height = this.height;
        var ctx = canvas.getContext("2d");
        ctx.drawImage(this, 0, 0);
        var dataURL = canvas.toDataURL("image/png");
        return dataURL;
    };
}
// send the request
request.send();
Run Code Online (Sandbox Code Playgroud)

这是该解决方案的最基本版本,不包括检索 XML 时的错误处理。这个 inline-svg 处理程序(大约第 110 行)演示了更好的错误处理,我从中导出了该方法的一部分。