我想通过 JavaScript 将 SVG 转换为位图图像(如 JPEG、PNG 等)。
我想通过 JavaScript 将 SVG 转换为位图图像(如 JPEG、PNG 等)。
使用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));
我最近发现了几个JavaScript图像追踪库,它们确实能够构建出一个大小和质量都可以接受的位图近似值。我正在开发这个JavaScript库和CLI:
https://www.npmjs.com/package/svg-png-converter
提供了统一的API,支持浏览器和节点,不依赖于DOM,并且有命令行工具。对于转换标志/卡通/类似图像,它表现出色。对于照片/逼真度,需要进行一些调整,因为输出大小可能会增加很多。它有一个游乐场,尽管现在我正在开发一个更好的游乐场,更易于使用,因为添加了更多功能:https://cancerberosgx.github.io/demos/svg-png-converter/playground/#
https://mybyways.com/blog/convert-svg-to-png-using-your-browser
在这个部分输入SVG代码,然后点击加载SVG按钮。 点击“保存SVG为PNG”按钮,将会显示SVG图像的预览,并可下载或保存为PNG图像文件。这是我的两分钱。在代码片段中,某种方式 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