我想通过JavaScript将SVG转换为位图图像(如JPEG, PNG等)。
当前回答
解决方案转换SVG到blob URL和blob URL到png图像
const svg=`<svg version="1.1" baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg"> <rect width="100%" height="100%" fill="red" /> <circle cx="150" cy="100" r="80" fill="green" /> <text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text></svg>` svgToPng(svg,(imgData)=>{ const pngImage = document.createElement('img'); document.body.appendChild(pngImage); pngImage.src=imgData; }); function svgToPng(svg, callback) { const url = getSvgUrl(svg); svgUrlToPng(url, (imgData) => { callback(imgData); URL.revokeObjectURL(url); }); } function getSvgUrl(svg) { return URL.createObjectURL(new Blob([svg], { type: 'image/svg+xml' })); } function svgUrlToPng(svgUrl, callback) { const svgImage = document.createElement('img'); // imgPreview.style.position = 'absolute'; // imgPreview.style.top = '-9999px'; document.body.appendChild(svgImage); svgImage.onload = function () { const canvas = document.createElement('canvas'); canvas.width = svgImage.clientWidth; canvas.height = svgImage.clientHeight; const canvasCtx = canvas.getContext('2d'); canvasCtx.drawImage(svgImage, 0, 0); const imgData = canvas.toDataURL('image/png'); callback(imgData); // document.body.removeChild(imgPreview); }; svgImage.src = svgUrl; }
其他回答
下面是你如何通过JavaScript来做到这一点:
使用Canvas JavaScript库渲染SVG图像:https://github.com/gabelerner/canvg 根据以下说明,从画布中捕获编码为JPG(或PNG)的数据URI:
我的用例是从网络加载svg数据,这个ES6类做了这项工作。
class SvgToPngConverter {
constructor() {
this._init = this._init.bind(this);
this._cleanUp = this._cleanUp.bind(this);
this.convertFromInput = this.convertFromInput.bind(this);
}
_init() {
this.canvas = document.createElement("canvas");
this.imgPreview = document.createElement("img");
this.imgPreview.style = "position: absolute; top: -9999px";
document.body.appendChild(this.imgPreview);
this.canvasCtx = this.canvas.getContext("2d");
}
_cleanUp() {
document.body.removeChild(this.imgPreview);
}
convertFromInput(input, callback) {
this._init();
let _this = this;
this.imgPreview.onload = function() {
const img = new Image();
_this.canvas.width = _this.imgPreview.clientWidth;
_this.canvas.height = _this.imgPreview.clientHeight;
img.crossOrigin = "anonymous";
img.src = _this.imgPreview.src;
img.onload = function() {
_this.canvasCtx.drawImage(img, 0, 0);
let imgData = _this.canvas.toDataURL("image/png");
if(typeof callback == "function"){
callback(imgData)
}
_this._cleanUp();
};
};
this.imgPreview.src = input;
}
}
下面是你如何使用它
let input = "https://restcountries.eu/data/afg.svg"
new SvgToPngConverter().convertFromInput(input, function(imgData){
// You now have your png data in base64 (imgData).
// Do what ever you wish with it here.
});
如果你想要一个普通的JavaScript版本,你可以访问Babel网站并在那里编译代码。
这是我的2美分。不知怎的,下载锚标签在代码片段中不像预期的那样工作,但在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>
Jbeard4解决方案工作得很好。
我使用Raphael SketchPad创建SVG。链接到步骤1中的文件。
对于保存按钮(svg的id是"editor", canvas的id是"canvas"):
$("#editor_save").click(function() {
// the canvg call that takes the svg xml and converts it to a canvas
canvg('canvas', $("#editor").html());
// the canvas calls to output a png
var canvas = document.getElementById("canvas");
var img = canvas.toDataURL("image/png");
// do what you want with the base64, write to screen, post to server, etc...
});
我最近发现了几个用于JavaScript的图像跟踪库,它们确实能够构建一个可接受的位图近似值,包括大小和质量。我正在开发这个JavaScript库和CLI:
https://www.npmjs.com/package/svg-png-converter
它为所有这些提供了统一的API,支持浏览器和节点,不依赖于DOM,以及命令行工具。
对于转换标志/卡通/喜欢的图像,它做得很好。对于照片/现实主义,需要一些调整,因为输出大小可以增长很多。
它有一个游乐场,虽然现在我正在做一个更好的,更容易使用,因为添加了更多的功能:
https://cancerberosgx.github.io/demos/svg-png-converter/playground/#
推荐文章
- 使用jQuery改变输入字段的类型
- 在JavaScript中,什么相当于Java的Thread.sleep() ?
- 使用jQuery以像素为整数填充或边距值
- 检查是否选择了jQuery选项,如果没有选择默认值
- Next.js React应用中没有定义Window
- 如何重置笑话模拟函数调用计数之前,每次测试
- 如何强制一个功能React组件渲染?
- 在javascript中从平面数组构建树数组
- 将Dropzone.js与其他字段集成到现有的HTML表单中
- 如何在AngularJS中观察路由变化?
- JavaScript DOM删除元素
- 将dd-mm-yyyy字符串转换为日期
- Javascript复选框onChange
- Javascript函数前导bang !语法
- 如何在页面上遍历所有DOM元素?