Firefox error rendering an SVG image to HTML5 canvas with drawImage

前端 未结 3 1213
失恋的感觉
失恋的感觉 2020-11-28 16:27

I am trying to convert an external svg icon to a base64 png using a canvas. It is working in all browsers except Firefox, which throws an error \"NS_ERROR_NOT_AVAILABLE\".

3条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-11-28 17:12

    As mentioned, this is an open bug caused by limitations on what Firefox accepts as specification for SVG sizes when drawing to a canvas. There is a workaround.

    Firefox requires explicit width and height attributes in the SVG itself. We can add these by getting the SVG as XML and modifying it.

    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;
    	
    	// 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(svg));
    	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();

    This is the most basic version of this solution, and includes no handling for errors when retrieving the XML. Better error handling is demonstrated in this inline-svg handler (circa line 110) from which I derived part of this method.

提交回复
热议问题