I am trying to convert an svg to an image format. Actually a lot works very fine and I know how to convert from SVG to canvas and from canvas to img. My problem is that the svg uses css that has been included as css file and by converting to canvas, the styles will be lost.
Does anyone has an idea how to copy the styles into my svg or canvas?
Here is my code: https://jsfiddle.net/DaWa/70w9db1d/
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>SVG2IMG</title>
<link rel="stylesheet" href="./circle.css">
</head>
<body>
<svg width="100" height="100">
<circle cx="50" cy="50" r="40"/>
</svg>
<script>
var svg = document.querySelector('svg');
let xml = new XMLSerializer().serializeToString(svg);
let data = "data:image/svg+xml;base64," + btoa(xml);
let img = new Image();
img.src = data;
document.body.appendChild(img)
</script>
</body>
</html>
And my css:
circle {
fill:red
}
I used this trick to add computed style of each node to its style attribute, and it works. may be it can help you.
Update 1: some browsers do not support the cssText property so you can use the code below which is a bit more cross browser.
Update 2: Firefox computes css quotes property which include some invalid string chars that btoa can not encode properly.
let addStyle = function(children) {
for (let i = 0; i < children.length; i++) {
let child = children[i];
if (child instanceof Element) {
let cssText = '';
let computedStyle = window.getComputedStyle(child, null);
for (let i = 0; i < computedStyle.length; i++) {
let prop = computedStyle[i];
cssText += prop + ':' + computedStyle.getPropertyValue(prop) + ';';
}
child.setAttribute('style', cssText);
addStyle(child.childNodes);
}
}
}
let svg = document.querySelector('svg');
addStyle(svg.childNodes);
let xml = new XMLSerializer().serializeToString(svg);
let data = "data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(xml)));
let img = new Image();
img.src = data;
document.body.appendChild(img);
circle {
fill: red
}
<svg width="100" height="100">
<circle cx="50" cy="50" r="40" />
</svg>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With