Quantcast
Channel: WP快站
Viewing all articles
Browse latest Browse all 233

how to convert my animated SVG in to GIF fromat

$
0
0
  • I didn't found any efficient solution right now,

  • I'm able to do it with puppeteer and FFmpeg but it takes time andalso did not get the resolution that I wanted.

currently, this approach launches svg in the browser through puppeteer and then takes snapshots in PNGs and after that combines those PNGs and makes gifbut this process is resource-intensive and also not get the solution that i wanted

this is my current approach, it is working but not efficient

let fs = require("fs");let child_process = require("child_process");const { exec } = require("child_process");let puppeteer = require("puppeteer");const usage = "usage: node index.js <svgPath> <duration> <fps> <outDir>";const imgExtention = "png";const imgType = "png";async function main() {  let [svgPath, duration, fps, outDir] = process.argv;  svgPath = "react-flow-canvas.svg";  duration = 4;  fps = 10;  outDir = "output";  if (outDir === undefined) {    console.error("outDir is not defined");    console.log(usage);    process.exit(2);  }  const svg = fs.readFileSync(svgPath, "utf-8");  duration = parseFloat(duration);  fps = parseInt(fps);  console.log("duration: " + duration +" s, fps: " + fps);  const totalFrames = Math.floor(fps * duration);  const digits = Math.floor(Math.log10(totalFrames)) + 1;  console.log("totalFrames: " + totalFrames);  process.chdir(outDir);  await createFrames(svg, fps, totalFrames, digits);  convertToMP4(fps, totalFrames, digits);}async function createFrames(svg, fps, totalFrames, digits) {  svg = svg.replace("--play-state: running;", "--play-state: paused;");  let browser = await puppeteer.launch({    headless: true,    args: ["--no-sandbox", "--font-render-hinting=none"],  });  let page = await browser.newPage();  await page.goto("about:blank");  await page.setContent(svg);  let renderSettings = {    type: imgType,    omitBackground: false,  };  console.log("creating frames");  for (let i = 1; i <= totalFrames; ++i) {    let result = await page.evaluate(function (startVal) {      document        .getElementsByTagName("svg")[0]        .style.setProperty("--start", startVal);    }, "" + (i - 1) / fps +"s");    await page.waitForTimeout(1);    let outputElem = await page.$("svg");    let prefix = ("" + i).padStart(digits, "0");    renderSettings.path = prefix +"." + imgExtention;    await outputElem.screenshot(renderSettings);    if (i % fps === 0 || i === totalFrames) {      console.log("progress: " + prefix +" / " + totalFrames);    }  }  await browser.close();  return totalFrames, digits;}function convertToMP4(fps, totalFrames, digits) {  console.log("running ffmpeg");  let output = child_process.execFileSync("ffmpeg",    ["-hide_banner","-loglevel","warning","-y","-framerate","" + fps,"-i","%0" + digits +"d." + imgExtention,"-c:v","libx264","-vf","fps=" + fps,"-pix_fmt","yuv420p","output.mp4",    ],    { encoding: "utf8" }  );  console.log(output);  exec("ffmpeg -i output.mp4 -qscale 200 output.gif");}main();

Please help me to do that in an efficient manner


Viewing all articles
Browse latest Browse all 233

Trending Articles