Quiero convertir SVG a imágenes de mapa de bits (como JPEG, PNG, etc.) a través de JavaScript.

  • ¿Qué tarea es lo que realmente se quiere lograr? Aunque echo de los flujos de respuesta nos dicen que es (en algunos navegadores) posible hay mejor y más fácil métodos de conversión para casi todos los casos prácticos.
  • He aquí un ejemplo de uso de d3: stackoverflow.com/a/23667012/439699
  • svgopen.org/2010/papers/62-From_SVG_to_Canvas_and_Back – Funciona a la perfección! [En la página de enlace, sourceSVG = $(«#your_svg_elem_name»).get(0) ]
InformationsquelleAutor Zain | 2010-10-20

9 Comentarios

  1. 234

    Aquí es cómo usted puede hacerlo a través de JavaScript:

    1. Utilizar el canvg biblioteca de JavaScript para procesar la imagen SVG, usando Canvas: https://github.com/gabelerner/canvg
    2. De captura de datos URI codificado como un JPG (o PNG) de la tela, de acuerdo a estas instrucciones: La captura de HTML Canvas como gif/jpg/png/pdf?
    • Esto no es estrictamente Javascript, HTML5, pero como bien. Esto no funciona en IE8, o cualquier otro navegador que no soporte el elemento Canvas de HTML5.
    • Si el navegador soporta SVG y canvas, entonces no sería una manera mucho más sencilla para cargar el SVG en la memoria y, a continuación, la pintura en un lienzo, sin la necesidad de Canvg, que es un bastante gran biblioteca, porque se encarga de todo el SVG de análisis que un SVG-apoyar navegador ya se ofrece de forma gratuita. No estoy seguro de si esto satisface el original de caso de uso, pero si es así, entonces ver este recurso para más detalles.
    • Gracias por no apoyar a los IE8. La gente debe entender que es tiempo de avanzar.
    • Ahora puede utilizar el JavaScript, SVG biblioteca Pablo para lograr esto (la hice yo). Consulte el toImage() y también download() para una auto-imagen descargada.
    • ¿cómo hacer esto? Todo lo que puedo conseguir es vacía archivo svg
    • svgopen.org/2010/papers/62-From_SVG_to_Canvas_and_Back – Funciona a la perfección! [En la página de enlace, sourceSVG = $(«#your_svg_elem_name»).get(0) ]
    • canvg es incompleta. por ejemplo, no es compatible con las máscaras.
    • Por desgracia, no funciona el link, pero tu comentario suena muy interesante.

  2. 43

    jbeard4 solución funcionaba a la perfección.

    Estoy usando Rafael SketchPad para crear un SVG. Enlace a los archivos en el paso 1.

    Para un botón de Guardar (id de svg es «editor», id de la tela es la «tela»):

    $("#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...
    });
    • canvg necesitan el segundo parámetro a <svg>...</svg pero jquery html() la función no agregar etiqueta svg, por lo que este código funciona para mí, pero yo necesitaba editar el canvg vivir a canvg('canvas', '<svg>'+$("#editor").html()+'</svg>');
    • si usted llama $(selector).html() en el padre de su svg elemento, va a trabajar
    • y @jonathanGB, usted no debería tener que usar html() en contenedores, o manualmente construir el padre svg etiqueta — que incluso podría tener los atributos de salir con este hack. Sólo uso $(svg_elem)[0].outerHTML le da el código fuente completo de la svg y su contenido. Acaba de decir…
  3. 13

    Esto parece funcionar en la mayoría de los navegadores:

    function copyStylesInline(destinationNode, sourceNode) {
    var containerElements = ["svg","g"];
    for (var cd = 0; cd < destinationNode.childNodes.length; cd++) {
    var child = destinationNode.childNodes[cd];
    if (containerElements.indexOf(child.tagName) != -1) {
    copyStylesInline(child, sourceNode.childNodes[cd]);
    continue;
    }
    var style = sourceNode.childNodes[cd].currentStyle || window.getComputedStyle(sourceNode.childNodes[cd]);
    if (style == "undefined" || style == null) continue;
    for (var st = 0; st < style.length; st++){
    child.style.setProperty(style[st], style.getPropertyValue(style[st]));
    }
    }
    }
    function triggerDownload (imgURI, fileName) {
    var evt = new MouseEvent("click", {
    view: window,
    bubbles: false,
    cancelable: true
    });
    var a = document.createElement("a");
    a.setAttribute("download", fileName);
    a.setAttribute("href", imgURI);
    a.setAttribute("target", '_blank');
    a.dispatchEvent(evt);
    }
    function downloadSvg(svg, fileName) {
    var copy = svg.cloneNode(true);
    copyStylesInline(copy, svg);
    var canvas = document.createElement("canvas");
    var bbox = svg.getBBox();
    canvas.width = bbox.width;
    canvas.height = bbox.height;
    var ctx = canvas.getContext("2d");
    ctx.clearRect(0, 0, bbox.width, bbox.height);
    var data = (new XMLSerializer()).serializeToString(copy);
    var DOMURL = window.URL || window.webkitURL || window;
    var img = new Image();
    var svgBlob = new Blob([data], {type: "image/svg+xml;charset=utf-8"});
    var url = DOMURL.createObjectURL(svgBlob);
    img.onload = function () {
    ctx.drawImage(img, 0, 0);
    DOMURL.revokeObjectURL(url);
    if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob)
    {
    var blob = canvas.msToBlob();         
    navigator.msSaveOrOpenBlob(blob, fileName);
    } 
    else {
    var imgURI = canvas
    .toDataURL("image/png")
    .replace("image/png", "image/octet-stream");
    triggerDownload(imgURI, fileName);
    }
    document.removeChild(canvas);
    };
    img.src = url;
    }
    • Esto no es trabajar en IE11, porque el tema de la seguridad con .msToBlob()
  4. 2

    Aquí está un servidor de solución basada en PhantomJS. Usted puede utilizar JSONP para hacer una cruz de dominio llame al servicio de la imagen:

    https://github.com/vidalab/banquo-server

    Por ejemplo:

    http://[host]/api/https%3A%2F%2Fvida.io%2Fdocuments%2FWgBMc4zDWF7YpqXGR/viewport_width=980&viewport_height=900&delay=5000&selector=%23canvas

    A continuación, puede ver la imagen con la etiqueta img:

    <img src="data:image/png;base64, [base64 data]"/>

    Funciona a través del navegador.

    • El servicio parece estar muerto.
    • Nuestro anfitrión había sido golpeado con falsas solicitudes. Así que decidimos ir hacia abajo. Usted tendrá que ejecutar su propio servidor ahora. Ver el repo de github para obtener más información.
  5. 0

    cambio svg para que coincida con su elemento

    function svg2img(){
    var svg = document.querySelector('svg');
    var xml = new XMLSerializer().serializeToString(svg);
    var svg64 = btoa(xml); //for utf8: btoa(unescape(encodeURIComponent(xml)))
    var b64start = 'data:image/svg+xml;base64,';
    var image64 = b64start + svg64;
    return image64;
    };svg2img()
  6. 0

    Recientemente he descubierto un par de calco de imagen de las bibliotecas de JavaScript que, de hecho, son capaces de construir una aproximación aceptable para el mapa de bits, tanto en tamaño como en calidad. Estoy desarrollo de esta biblioteca de JavaScript y de la CLI :

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

    Que proporciona una API unificada para todos ellos, el apoyo de navegador y el nodo, no dependiendo de DOM, y una herramienta de línea de Comandos.

    Para la conversión de logotipos/dibujos animados/imágenes similares a las que hace un excelente trabajo. Para las fotos /realismo algunos ajustes es necesario, ya que el tamaño de salida puede crecer mucho.

    Tiene una zona de juegos infantil, aunque justo ahora estoy trabajando en uno mejor, más fácil de usar, ya que más de las características ha añadido:

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

  7. 0

    Escribí esto ES6 Clase que hace todo el Trabajo.

    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;
    }
    }

    Aquí es cómo usted lo utiliza

    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.
    });

    Si quieres un vainilla versión de JavaScript, podría pásate Babel sitio web y transpile el código allí.

  8. 0

    La solución para convertir SVG a blob URL y URL blob a imagen png

    JS:

    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;
    }

  9. 0

    Svg a png se puede convertir dependiendo de las condiciones:

    1. Si svg es en formato SVG (cadena) rutas:
      • crear lienzo
      • crear new Path2D() y establecer svg como parámetro
      • trazar ruta en lienzo
      • crear la imagen y el uso canvas.toDataURL() como src.

    ejemplo:

    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    let svgText = 'M10 10 h 80 v 80 h -80 Z';
    let p = new Path2D('M10 10 h 80 v 80 h -80 Z');
    ctx.stroke(p);
    let url = canvas.toDataURL();
    const img = new Image();
    img.src = url;

    Nota que Path2D no se admite en ie y parcialmente apoyado en el borde. El polyfil resuelve que:
    https://github.com/nilzona/path2d-polyfill

    1. Crear svg blob y dibujar sobre el lienzo utilizando .drawImage():
      • realizar elemento canvas
      • hacer un svgBlob objeto de la svg xml
      • hacer un objeto url de domUrl.createObjectURL(svgBlob);
      • crear un objeto de Imagen y asignar la url de la imagen src
      • dibujar la imagen en el lienzo
      • obtener png de datos de cadena de lona: lienzo.toDataURL();

    Buena descripción:
    http://ramblings.mcpher.com/Home/excelquirks/gassnips/svgtopng

    Nota que en ie obtendrá excepción en el escenario de la lona.toDataURL(); Esto es debido a que el IE tiene demasiado alta restricción de seguridad y trata de lona como readonly después de dibujar la imagen allí. Todos los demás navegadores restringir sólo si la imagen es el origen de la cruz.

    1. Uso canvg biblioteca de JavaScript. Es independiente de la biblioteca, pero tiene funciones útiles.

    Como:

    ctx.drawSvg(rawSvg);
    var dataURL = canvas.toDataURL();

Dejar respuesta

Please enter your comment!
Please enter your name here