webentwicklung-frage-antwort-db.com.de

Konvertieren Sie SVG in ein Bild (JPEG, PNG usw.) im Browser

Ich möchte SVG in Bitmap-Bilder (wie JPEG, PNG usw.) über JavaScript konvertieren.

273
Zain

So können Sie es mit JavaScript tun:

  1. Verwenden Sie die JavaScript-Bibliothek canvg, um das SVG-Bild mit Canvas zu rendern: https://github.com/gabelerner/canvg
  2. Erfassen Sie eine als JPG (oder PNG) codierte Daten-URI aus dem Canvas-Bereich gemäß den folgenden Anweisungen: HTML-Canvas als gif/jpg/png/pdf erfassen?
232
jbeard4

die jbeard4-Lösung hat wunderbar funktioniert.

Ich benutze Raphael SketchPad um eine SVG zu erstellen. Verknüpfen Sie mit den Dateien in Schritt 1.

Für eine Schaltfläche Speichern (ID von SVG ist "Editor", ID von Canvas ist "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...
});
43
coop

Dies scheint in den meisten Browsern zu funktionieren:

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

Hier ist eine serverseitige Lösung, die auf PhantomJS basiert. Mit JSONP können Sie einen domänenübergreifenden Aufruf an den Image-Service senden:

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

Zum Beispiel:

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

Dann können Sie das Bild mit dem Tag img anzeigen:

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

Es funktioniert browserübergreifend.

2
Phuoc Do

Ich habe diese ES6-Klasse geschrieben, die den Job macht.

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

So verwenden Sie es

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

Wenn Sie eine Vanilla-JavaScript-Version möchten, können Sie gehen Sie zur Babel-Website und den Code dort transpilieren.

0
Cels

Vor kurzem habe ich ein paar Bildverfolgungsbibliotheken für JavaScript entdeckt, die tatsächlich eine akzeptable Annäherung an die Bitmap herstellen können, sowohl in Größe als auch in Qualität. Ich entwickle diese JavaScript-Bibliothek und CLI:

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

Die einheitliche API für alle bietet, Browser und Knoten unterstützt, unabhängig von DOM, und ein Befehlszeilentool.

Zum Konvertieren von Logos/Cartoons/ähnlichen Bildern ist es hervorragend geeignet. Für Fotos/Realismus sind einige Optimierungen erforderlich, da die Ausgabegröße stark ansteigen kann.

Es gibt einen Spielplatz, obwohl ich gerade an einem besseren arbeite, der benutzerfreundlicher ist, da weitere Funktionen hinzugefügt wurden:

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

0
cancerbero

ändere svg so, dass es zu deinem Element passt

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()
0
Mahdi Khalili