问题描述
我需要将2个独立的SVG转换为1个PNG图像。我目前有将1 SVG转换为PNG的代码。该代码如下所示,我将SVG转换为canvas到PNG。
SVG位于同一页面上,我尝试使用数组来遍历它们并同时获取它们。我当前正在处理的代码也在下面,但无法正常工作。关于如何将SVG转换为相同的PNG图像的任何建议?
谢谢!
将单个SVG转换为PNG
// convert svg to png
function svgToPng(){
var svg = document.querySelectorAll('svg')[0];
// clone svg nodes
var copy = svg.cloneNode(true);
// convert to xml format for storage/transportation
var serializer = new XMLSerializer();
var data = serializer.serializetoString(copy);
// create url
var DOMURL = window.URL || window.webkitURL || window;
// create image/blob
var img = new Image();
var blob = new Blob([data],{type: "image/svg+xml;charset=utf-8"});
var url = DOMURL.createObjectURL(blob);
// create canvas
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
// draw image on canvas
img.onload = function(){
ctx.drawImage(img,$(svg0).width(),$(svg0).height());
DOMURL.revokeObjectURL(url,url1);
var imgurI = canvas.toDataURL("image/png").replace("image/png","image/octet-stream");
}
// send new image to window
img.src = url;
// return img.src;
window.open().document.write('<img src="' + img.src + '" width="1600" height="800"/>');
};
多个SVG到PNG
// convert multipl svgs to png
function multSvgToPng(){
var array = [];
var totalSvg = document.querySelectorAll('svg'); // NodeList(2) [svg,svg]
// create array
for(var i = 0; i < totalSvg.length; i++){
array = document.querySelectorAll('svg')[i];
}
for(var j = 0; j < array.length; j++){
var svg = array[j];
var copy = svg.cloneNode(true);
var serializer = new XMLSerializer();
var data = serializer.serializetoString(copy);
var DOMURL = window.URL || window.webkitURL || window;
var img = new Image();
var blob = new Blob([data],{type: "image/svg+xml;charset=utf-8"});
var url = DOMURL.createObjectURL(blob);
var svgStr = serializer.serializetoString(copy);
}
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
img.onload = function(){
ctx.drawImage(img,$(svg).width(),$(svg).height());
DOMURL.revokeObjectURL(url);
var imgurI = canvas.toDataURL("image/png").replace("image/png","image/octet-stream");
}
// send new image to window
img.src = url;
// return img.src;
window.open().document.write('<img src="' + img.src + '" width="1600" height="800"/>');
}
SVG图片示例
解决方法
我已经使用了您的技术,并完成了两个单独的功能。第一个功能drawSVGToCanvas
为单个SVG创建画布,方法是将其转换为blob,并在加载图像后将其绘制到画布上。装满画布后,它会返回canvas的promise。
convertSVGsToSingleImage
接受一个SVG元素列表,它将为其循环并为每个SVG元素调用drawSVGToCanvas
。它等待直到它们被渲染,然后继续在单个新画布上绘制返回的画布元素。这是合并发生的地方。
const preview = document.getElementById('preview');
const svgs = document.querySelectorAll('svg');
function drawSVGToCanvas(svg) {
const { width,height } = svg.getBoundingClientRect();
const serializer = new XMLSerializer();
const copy = svg.cloneNode(true);
const data = serializer.serializeToString(copy);
const image = new Image();
const blob = new Blob([data],{
type: 'image/svg+xml;charset=utf-8'
});
const url = URL.createObjectURL(blob);
return new Promise(resolve => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = width;
canvas.height = height;
image.addEventListener('load',() => {
ctx.drawImage(image,width,height);
URL.revokeObjectURL(url);
resolve(canvas);
},{ once: true });
image.src = url;
})
}
async function convertSVGsToSingleImage(svgs,format = 'image/png') {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const drawSVGs = Array.from(svgs).map(svg => drawSVGToCanvas(svg))
const renders = await Promise.all(drawSVGs);
canvas.width = Math.max(...renders.map(render => render.width));
canvas.height = Math.max(...renders.map(render => render.height));
renders.forEach(render => ctx.drawImage(render,render.width,render.height));
const source = canvas.toDataURL(format).replace(format,'image/octet-stream');
return source;
}
convertSVGsToSingleImage(svgs).then(source => {
const image = new Image();
image.addEventListener('load',() => {
preview.append(image);
})
image.src = source;
});
<svg width="400" height="110">
<rect width="300" height="100" style="fill:rgb(0,255);stroke-width:3;stroke:rgb(0,0)" />
Sorry,your browser does not support inline SVG.
</svg>
<svg height="100" width="100">
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
Sorry,your browser does not support inline SVG.
</svg>
<div id="preview"></div>