web-dev-qa-db-ja.com

ブラウザでSVGを画像(JPEG、PNGなど)に変換します。

SVGをJavaScriptでビットマップ画像(JPEG、PNGなど)に変換したい。

273
Zain

JavaScriptでそれを実現する方法は次のとおりです。

  1. Canvasを使用してSVG画像をレンダリングするには、canvg JavaScriptライブラリを使用します。 https://github.com/gabelerner/canvg
  2. 次の手順に従って、キャンバスからJPG(またはPNG)としてエンコードされたデータURIをキャプチャします。 HTMLキャンバスをgif/jpg/png/pdfとしてキャプチャしますか?
229
jbeard4

jbeard4ソリューションは美しく機能しました。

SVGを作成するために Raphael SketchPad を使用しています。手順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...
});
42
coop

これはほとんどのブラウザでうまくいくようです。

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

これがPhantomJSをベースにしたサーバサイドソリューションです。 JSONPを使用して、イメージサービスへのクロスドメイン呼び出しを行うことができます。

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

例えば:

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

次に、imgタグ付きの画像を表示することができます。

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

ブラウザを越えて動作します。

2
Phuoc Do

仕事をするこの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のWebサイトに移動 でコードを変換できます。

0
Cels

私は最近、サイズと品質の両方で、ビットマップの許容可能な近似値を実際に構築できるJavaScript用の画像トレースライブラリをいくつか発見しました。私はこのJavaScriptライブラリとCLIを開発しています:

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

DOMに依存しないブラウザーとノードをサポートするすべての統合APIとコマンドラインツールを提供します。

ロゴ/漫画/画像を変換するために、それは素晴らしい仕事をします。写真/リアリズムの場合、出力サイズが大きくなる可能性があるため、微調整が必​​要です。

遊び場がありますが、現在はより良いものに取り組んでおり、より使いやすく、より多くの機能が追加されています:

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

0
cancerbero

あなたの要素に合うようにsvgを変更してください

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