web-dev-qa-db-ja.com

インラインSVGをJPEG / PNG / SVGとして保存する

HTMLにインラインSVGがあり、これをJPEG、PNG、またはSVGとして保存できるようにする必要があります。

SVGをキャンバスに変換してからJPEGに変換する方法をいくつか試しましたが、これらを機能させることはできませんでした。

これが私のインラインSVGの例です。

.font {
        color: #ffffff;
        font-family: Roboto;
        font-weight: bold;
        text-transform: uppercase;
}
.name {
        font-size: 64pt;
}
.top-bar-text {
        font-size: 32pt;
}
.font tspan {
        dominant-baseline: middle;
}
<link href='http://fonts.googleapis.com/css?family=Roboto:700' rel='stylesheet' type='text/css'>

<svg width="256" height="256" id="icon">
  <rect class="bg1" id="bg_color_1" x="0" y="0" width="256" height="256" fill="#4cbc5a" />
  <path class="bg2" id="bg_color_2" d="M 0 96 L0,256 L256,256 L256,96 s -128 96 -256 0" fill="#08a21c" />
  <text id="left_corner_text" x="24" y="36" width="48" height="64" class="top_bar lct font top-bar-text" text-anchor="middle" fill="#ffffff"><tspan>1</tspan></text>
  <text id="right_corner_text" x="232" y="36" width="48" height="64" class="top_bar rct font top-bar-text" text-anchor="middle" fill="#ffffff"><tspan>2</tspan></text>
  <text id="line_1_text" transform="scale(1,2)" x="128" y="90" width="256" height="192" class="l1t font name" text-anchor="middle" fill="#ffffff"><tspan>ABC</tspan></text>
</svg>

また、すべての要素をエクスポートする必要はありません。ユーザーが使用できるオプションの一部は、上部のコーナー番号を削除することです。

ブラウザに直接ダウンロードするように変換されたときを希望します。

29

現在、これは非常に簡単です。

基本的な考え方は次のとおりです。

  1. キャンバスにsvg
  2. キャンバスからdataUrl
  3. dataUrlからのダウンロードのトリガー

実際にはstackoverflowスニペットの外で動作します

var btn = document.querySelector('button');
var svg = document.querySelector('svg');
var canvas = document.querySelector('canvas');

function triggerDownload (imgURI) {
  var evt = new MouseEvent('click', {
    view: window,
    bubbles: false,
    cancelable: true
  });

  var a = document.createElement('a');
  a.setAttribute('download', 'MY_COOL_IMAGE.png');
  a.setAttribute('href', imgURI);
  a.setAttribute('target', '_blank');

  a.dispatchEvent(evt);
}

btn.addEventListener('click', function () {
  var canvas = document.getElementById('canvas');
  var ctx = canvas.getContext('2d');
  var data = (new XMLSerializer()).serializeToString(svg);
  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);

    var imgURI = canvas
        .toDataURL('image/png')
        .replace('image/png', 'image/octet-stream');

    triggerDownload(imgURI);
  };

  img.src = url;
});
<button>svg to png</button>

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="200" height="200">
  <rect x="10" y="10" width="50" height="50" />
  <text x="0" y="100">Look, i'm cool</text>
</svg>

<canvas id="canvas"></canvas>

ダウンロード部分については、ファイル名などを設定できます(ただし、この例には含まれていません)。先日、特定のページからHTMLの特定の部分をダウンロードする方法に関する質問に答えました。ダウンロード部分に関しては役に立つかもしれません: https://stackoverflow.com/a/28087280/217818

update:ファイル名を指定できるようになりました

53
Ciro Costa

IE11でも同様に機能するソリューションがあります。

私はこれについてさまざまな方法をテストしましたが、Ciro Costaによる上記の答えはFirefoxで動作するという点で素晴らしいですが、Chrome IE11では動作しません。IE11 セキュリティの問題のために失敗します キャンバス実装を必要とするキャンバスにsvgをレンダリングする場合、 canvg 。かなり簡潔で最新のもので動作するcanvgを使用したソリューションは次のとおりです。 Chrome、Firefox、Edge、およびIE11のバージョン。

フィドル:https://jsfiddle.net/StefanValentin/9mudw0ts/

[〜#〜] dom [〜#〜]

<svg
  id="my-svg"
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  version="1.1"
  width="200"
  height="200"
>
  <rect x="10" y="10" width="50" height="50" />
  <text x="0" y="100">Look, i'm cool</text>
</svg>

JavaScript

var svg = document.querySelector('#my-svg');
var data = (new XMLSerializer()).serializeToString(svg);
// We can just create a canvas element inline so you don't even need one on the DOM. Cool!
var canvas = document.createElement('canvas');
canvg(canvas, data, {
  renderCallback: function() {
    canvas.toBlob(function(blob) {
        download('MyImageName.png', blob);
    });
  }
});

上記のdownload関数は、JavaScriptを介してダウンロードをトリガーする多くの方法があるため、何でもできます。これが、私がテストしたすべてのブラウザーで機能するものです。

// Initiate download of blob
function download(
  filename, // string
  blob // Blob
) {
  if (window.navigator.msSaveOrOpenBlob) {
    window.navigator.msSaveBlob(blob, filename);
  } else {
    const elem = window.document.createElement('a');
    elem.href = window.URL.createObjectURL(blob);
    elem.download = filename;
    document.body.appendChild(elem);
    elem.click();
    document.body.removeChild(elem);
  }
}
1
KhalilRavanna

@CiroCostaでの作業。要素のエクスポートに問題がある場合は、svg画像を描画する前に画像をキャンバスに描画するだけでよい1つのオプション

    btn.addEventListener('click', function () {
      var canvas = document.getElementById('canvas');
      var ctx = canvas.getContext('2d');
      var data = (new XMLSerializer()).serializeToString(svg);
      var DOMURL = window.URL || window.webkitURL || window;

// get the raw image from the DOM
      var rawImage = document.getElementById('yourimageID');
      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(rawImage, 0, 0);
        ctx.drawImage(img, 0, 0);
        DOMURL.revokeObjectURL(url);

        var imgURI = canvas
            .toDataURL('image/png')
            .replace('image/png', 'image/octet-stream');

        triggerDownload(imgURI);
      };

      img.src = url;
    });

私のために働いたが、PNGとJPEGのみでした。 SVGファイルは引き続きインライン要素のみを表示し、タグは表示しません

編集:このようなsvgを作成する方法は、実際には画像タグをBase64に変換し、次のような画像属性のxlink:hrefとして設定することです。

<image id="crop" width="725" height="1764" xlink:href="data:image/png;base64,iVBORw0KGgo ... " />

そして、次のようにsvg URL全体でダウンロードをトリガーします:

btn.addEventListener('click', function () {
      var canvas = document.getElementById('canvas');
      var ctx = canvas.getContext('2d');
      var data = (new XMLSerializer()).serializeToString(svg);
      var DOMURL = window.URL || window.webkitURL || window;

      var rawImage = document.getElementById('yourimageID');
      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);


       triggerDownload(url);
       DOMURL.revokeObjectURL(url);
      }
};

次のようにpngを変換できます here

function getDataUri(url, callback) {
            var image = new Image();

            image.onload = function () {
                var canvas = document.createElement('canvas');
                canvas.width = this.naturalWidth; // or 'width' if you want a special/scaled size
                canvas.height = this.naturalHeight; // or 'height' if you want a special/scaled size

                canvas.getContext('2d').drawImage(this, 0, 0);

                // Get raw image data
                callback(canvas.toDataURL('image/png').replace(/^data:image\/(png|jpg);base64,/, ''));

                // ... or get as Data URI
                callback(canvas.toDataURL('image/png'));
            };

            image.src = url;
        }

次に、属性を設定します

getDataUri('localImagepath', function(dataUri) {
       image.setAttribute('xlink:href',dataUri);
});
0
Chadd Frasier