在浏览器中将SVG转换为图像(JPEG,PNG等)

388

我想通过 JavaScript 将 SVG 转换为位图图像(如 JPEG、PNG 等)。


你实际想要完成什么任务?尽管echo-flows的答案告诉我们(在某些浏览器中)这是可能的,但对于几乎所有实际情况,都有更好、更简单的转换方法。 - aaaaaaaaaaaa
2
这里有一个使用d3的例子:https://dev59.com/zmgu5IYBdhLWcg3wHjh7#23667012 - ace
http://svgopen.org/2010/papers/62-From_SVG_to_Canvas_and_Back/ - 完美地运行![在链接页面上,sourceSVG = $(“your_svg_elem_name”).get(0)] - Vijay Singh
相关:https://dev59.com/WXA75IYBdhLWcg3wqK__ - mathheadinclouds
https://mybyways.com/blog/convert-svg-to-png-using-your-browser - natenho
这个回答解决了你的问题吗?如何将HTML Canvas保存为gif/jpg/png/pdf格式? - Carson
14个回答

1

使用Canvg库有几种将SVG转换为PNG的方法。

在我的情况下,我需要从内联SVG获取PNG blob

该库文档提供了一个示例(请参见OffscreenCanvas示例)。

但是这种方法目前在Firefox中不起作用。 是的,您可以在设置中启用gfx.offscreencanvas.enabled选项。 但是每个站点上的每个用户都会这样做吗? :)

但是,还有另一种方法,也适用于Firefox。

const el = document.getElementById("some-svg"); //this is our inline SVG

var canvas = document.createElement('canvas'); //create a canvas for the SVG render
canvas.width = el.clientWidth; //set canvas sizes
canvas.height = el.clientHeight;

const svg = new XMLSerializer().serializeToString(el); //convert SVG to string

//render SVG inside canvas
const ctx = canvas.getContext('2d');
const v = await Canvg.fromString(ctx, svg);
await v.render();

let canvasBlob = await new Promise(resolve => canvas.toBlob(resolve));

最后一行感谢this的回答。

1

我最近发现了几个JavaScript图像追踪库,它们确实能够构建出一个大小和质量都可以接受的位图近似值。我正在开发这个JavaScript库和CLI:

https://www.npmjs.com/package/svg-png-converter

提供了统一的API,支持浏览器和节点,不依赖于DOM,并且有命令行工具。对于转换标志/卡通/类似图像,它表现出色。对于照片/逼真度,需要进行一些调整,因为输出大小可能会增加很多。它有一个游乐场,尽管现在我正在开发一个更好的游乐场,更易于使用,因为添加了更多功能:

https://cancerberosgx.github.io/demos/svg-png-converter/playground/#


0
如果目标是通过浏览器将SVG文件转换为PNG图像文件,也许以下网站可以帮助那些需要快速完成的人:

https://mybyways.com/blog/convert-svg-to-png-using-your-browser

enter image description here

在这个部分输入SVG代码,然后点击加载SVG按钮。

enter image description here

点击“保存SVG为PNG”按钮,将会显示SVG图像的预览,并可下载或保存为PNG图像文件。

0

这是我的两分钱。在代码片段中,某种方式 Download 锚标签的工作不如预期,但在 Chrome 中它可以正常工作。

这里是可用的 jsFiddle

const waitForImage = imgElem => new Promise(resolve => imgElem.complete ? resolve() : imgElem.onload = imgElem.onerror = resolve);

const svgToImgDownload = ext => {
  if (!['png', 'jpg', 'webp'].includes(ext))
    return;
  const _svg = document.querySelector("#svg_container").querySelector('svg');
  const xmlSerializer = new XMLSerializer();
  let _svgStr = xmlSerializer.serializeToString(_svg);
  const img = document.createElement('img');
  img.src = 'data:image/svg+xml;base64,' + window.btoa(_svgStr);
  waitForImage(img)
    .then(_ => {
      const canvas = document.createElement('canvas');
      canvas.width = _svg.clientWidth;
      canvas.height = _svg.clientHeight;
      canvas.getContext('2d').drawImage(img, 0, 0, _svg.clientWidth, _svg.clientHeight);
      return canvas.toDataURL('image/' + (ext == 'jpg' ? 'jpeg' : ext), 1.0);
    })
    .then(dataURL => {
      console.log(dataURL);
      document.querySelector("#img_download_btn").innerHTML = `<a href="${dataURL}" download="img.${ext}">Download</a>`;
    })
    .catch(console.error);
};

document.querySelector('#map2Png').addEventListener('click', _ => svgToImgDownload('png'));
document.querySelector('#map2Jpg').addEventListener('click', _ => svgToImgDownload('jpg'));
document.querySelector('#map2Webp').addEventListener('click', _ => svgToImgDownload('webp'));
<div id="svg_container" style="float: left; width: 50%">
  <svg width="200" height="200" viewBox="-100 -100 200 200">
    <circle cx="0" cy="20" r="70" fill="#D1495B" />
    <circle cx="0" cy="-75" r="12" fill="none" stroke="#F79257" stroke-width="2" />
    <rect x="-17.5" y="-65" width="35" height="20" fill="#F79257" />
  </svg>
</div>

<div>
  <button id="map2Png">PNG</button>
  <button id="map2Jpg">JPG</button>
  <button id="map2Webp">WEBP</button>
</div>

<div id="img_download_btn"></div>


if (!['jpg'].includes(ext)) return and ext == 'jpg' ? 'jpeg' will never reach if someone uses jpeg, guessing you meant ['png','jpg','jpeg','webp'] - Ol Sen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接