My ultimate goal is that I'm trying to convert an animated SMIL SVG into an APNG file. I have found no easy way to do this, and so I'm doing something a roundabout: I've written a node.js + express.js app that hosts a simple backend to get svg images on my local filesystem, and I've written a vue.js app that will go and pull those images and render them on a google chrome browser. I then play the SVG and try to capture rendered "frames", and save those frames as static png files (about 30 static PNG files for each second of SVG animation). I then plan to take those static png files & convert them over to a single animated png / apng file using another program. The part that I'm stuck on: actually trying to capture a rasterized "frame" of the svg.
Here's a snippet of code from my vue.js app which requests an SVG file, and renders it to a div, and then it tries to call a function takeSnap()
.
const file = await RequestsService.getFile(i);
const div = document.getElementById("svgContainer");
div.innerHTML = file.svg;
const { width, height } = div.children[0].getBBox();
console.debug(`width: ${width}, height: ${height}`);
const svg = div.children[0];
await svg.pauseAnimations();
let time = 0.0;
const interval = 1.0 / numFrames; // interval in seconds.
let count = 0;
while (time < file.duration) {
console.log(`time=${time}`);
await svg.setCurrentTime(time);
await this.takeSnap(svg, width, height);
time += interval;
console.debug(`file: ${file.fileName}_${count}`);
}
await svg.setCurrentTime(file.duration);
await this.takeSnap(svg, width, height);
I haven't been able to make a proper implementation of takeSnap()
. I know that there are a slew of tools such as Canvg or HTML2png that go and directly render a webpage from the DOM. I've tried many different libraries, but none of them seem to be able to correctly render the frame of the SVG that chrome is correctly rendering. I don't blame the libraries: going from animated SVG XML file to actually rasterized pixels is a very difficult problem I think. But Chrome can do it, and what I'm wondering is... can I capture the browser engine output of chrome somehow?
Is there a way that I can get the rasterized pixel data produced by the blink browser engine in chrome & then save that rasterized pixel data into a png file? I know that I'll lose the transparency data of the SVG, but that's okay, I'll work around that later.