web-dev-qa-db-ja.com

インラインsvg(DOM)をキャンバスに描画する方法は?

まあ、私は.svgファイル/画像を.pngファイル/画像に変換するための助けが必要です...

ページに.svg画像が表示されています。サーバーに保存されます(.pngファイルとして)。オンデマンドで(ボタンをクリックして).pngファイルに変換し、サーバーに.pngファイルを保存する必要があります(これは.ajaxリクエストで行います)。

しかし、問題は変換です。

私はhtml5 Canvasについて多くのことを読みました。これはおそらく今やるべきことをするのに役立つかもしれませんが、私の問題に対する明確な解決策を見つけることができません。私がそれをしなければならない方法についていくつかの明確なアドバイス/助けが必要です。

「html idea」テンプレートは次のとおりです。

<html>
    <body>
        <svg id="mySvg" width="300px" height="300px">
            <!-- my svg data -->
        </svg>
        <label id="button">Click to convert</label>
        <canvas id="myCanvas"></canvas>
    </body>
</html>

そしていくつかのjs:

<script>
    $("body").on("click","#button",function(){
        var svgText = $("#myViewer").outerHTML;
        var myCanvas = document.getElementById("canvas");
        var ctxt = myCanvas.getContext("2d");
    });
</script>

次に、svgをCanvasに描画し、base64データを取得して、サーバー上の.pngファイルに保存する必要があります...しかし...どうやって?私は実際に...多くの異なるソリューションについて読みました...私は... jsfiddleに取り組んでいますが、実際には...どこにもありません... http://jsfiddle.net/xfh7nctk/6 / ...お読みいただきありがとうございます/ヘルプ

27
Julo0sS

インラインSVGの場合:

  • SVG文字列をBlobに変換します
  • BlobのURLを取得します
  • 画像要素を作成し、URLをsrcとして設定します
  • ロードされたとき(onload)、SVGを画像としてキャンバスに描画できます
  • toDataURL()を使用して、キャンバスからPNGファイルを取得します。

例えば:

function drawInlineSVG(ctx, rawSVG, callback) {

    var svg = new Blob([rawSVG], {type:"image/svg+xml;charset=utf-8"}),
        domURL = self.URL || self.webkitURL || self,
        url = domURL.createObjectURL(svg),
        img = new Image;

    img.onload = function () {
        ctx.drawImage(this, 0, 0);     
        domURL.revokeObjectURL(url);
        callback(this);
    };

    img.src = url;
}

// usage:
drawInlineSVG(ctxt, svgText, function() {
    console.log(canvas.toDataURL());  // -> PNG data-uri
});

もちろん、ここのconsole.logは単なる例です。代わりにここに文字列を保存/転送します。 (メソッド内にonerrorハンドラーを追加することもお勧めします)。

また、widthおよびheight属性を使用して、またはプロパティを使用してJavaScriptからキャンバスサイズを設定することを忘れないでください。

42
user1693593

受け入れられた答えが望ましくない行動を引き起こす可能性があるため、私はこの質問から他の質問が提起されてからずっと後になります。

@ K3Nソリューションはほぼ正しいですが、私は_svgElement.outerHTML_の使用に反対します。
代わりに、 new XMLSerializer().serializeToString(svgElement) を優先する必要があります。

また、blobとURL APIを使用する必要はなく、単純なdataURIはブラウザー間でより互換性があります。

したがって、これの完全なバージョンは次のようになります。

_function drawInlineSVG(svgElement, ctx, callback){
  var svgURL = new XMLSerializer().serializeToString(svgElement);
  var img  = new Image();
  img.onload = function(){
    ctx.drawImage(this, 0,0);
    callback();
    }
  img.src = 'data:image/svg+xml; charset=utf8, '+encodeURIComponent(svgURL);
  }

//usage :
drawInlineSVG(document.querySelector('svg'), ctxt, function(){console.log(canvas.toDataURL())})
_
27
Kaiido