简体   繁体   中英

How to convert multiple SVG's to one PNG image?

I need to convert 2 separate SVG's into 1 PNG image. I currently have code working for converting 1 SVG to a PNG. This code is shown below, I convert the SVG to canvas to PNG.

The SVG's are on the same page, and I have tried using an array to iterate through them and grab both. The code I am currently working on is also below, but is not working. Any advice on how to convert the SVGs to the same PNG image?

Thanks a bunch!

Single SVG to 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, 0, 0, $(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"/>'); };

Multiple SVG's to 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, 0, 0, $(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"/>'); }

Example SVG Images

 <!DOCTYPE html> <html> <body> <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> </body> </html>

 <!DOCTYPE html> <html> <body> <svg width="400" height="110"> <rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" /> Sorry, your browser does not support inline SVG. </svg> </body> </html>

I've used your technique and made two separate functions. The first function drawSVGToCanvas creates a canvas for a single SVG, by converting it to a blob and drawing it onto the canvas when the image has loaded. It returns a promise with the canvas element when it is fullfilled.

convertSVGsToSingleImage accepts a list of SVG elements for which it will loop over and call drawSVGToCanvas for each of those SVG elements. It waits until they are rendered and continues to draw the returned canvas elements on a single new canvas. This is where the combining happens.

 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, 0, 0, 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, 0, 0, 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,0,255);stroke-width:3;stroke:rgb(0,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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM