SVG画像を canvgでCanvas に変換してみる
SVG画像を canvgでCanvas に変換してみる
SVG画像を canvgでCanvas で扱えるように変換してみたのでメモ。
canvg とは
SVGコードをCanvas用のコードへ変換してくれるJavaScriptライブラリです。 MITライセンスで、GitHubにも挙がってます。
今回使用したのは、こちらのcanvasgで作られているWebサービスです。 SVGコードを貼り付けると、Canvasでpreview し、かつCanvas用のコードを返してくれます。
類似ツール
SVGのようなベクターデータをCanvas コードに変換してれる類似ツールはいくつかあるので、 まとめておきます。
-
Drawscript
Illustrator のプラグイン。 Creativei Cloud 利用できる環境でインストールできるようです。 Illusrtror で描いたデータをCanvasやCreateJSのコードに変換できます。
-
Toolkit for CreateJS
Flash のプラグインです。 Flashで生成したデータを CreateJS(Canvas)のコードへ変換できます。 CreateJSでアニメーションを作るときに、コード直書きするよりもこっちのほうが使われていそう。
-
ink2canvas
Inkscape の拡張機能としてインストールできるようです。 3, 4年前から更新が止まっているようなので使うのは難しいかもしれません。
サンプル
以下のInkscapeで描いたSVG画像を、Canvas用のコードに変化したいと思います。
ちなみコードは、以下の様になっています。
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
version="1.1"
id="svg2"
viewBox="0 0 225 225"
height="225"
width="225">
<defs
id="defs4" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
style="display:inline"
transform="translate(-178,-203.56851)"
id="layer1" />
<g
transform="translate(-0.5,0.57940674)"
style="display:inline;opacity:1"
id="layer2">
<circle
r="110"
cy="111.92059"
cx="113"
id="path3336"
style="opacity:1;fill:#ffff00;fill-opacity:1;stroke:#000000;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<g
transform="translate(-0.5,0.57940674)"
id="layer4">
<path
d="m 163,173.19968 a 50,21.087877 0 0 1 -25,18.26263 50,21.087877 0 0 1 -50.000001,0 A 50,21.087877 0 0 1 63,173.19968"
id="path4157"
style="display:inline;opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<g
transform="translate(-0.5,0.57940674)"
style="display:inline"
id="layer3">
<g
id="layer5">
<circle
r="20"
cy="100.36712"
cx="77.318108"
id="path3338"
style="display:inline;opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<g
style="display:inline"
id="layer7">
<circle
r="20"
cy="100.36712"
cx="155.5"
id="path3338-4"
style="display:inline;opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
</g>
</svg>
変換した結果はこちら。
生成されたCanvasコードは以下です。
var draw = function(ctx) {
ctx.save();
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(225,0);
ctx.lineTo(225,225);
ctx.lineTo(0,225);
ctx.closePath();
ctx.clip();
ctx.translate(0,0);
ctx.translate(0,0);
ctx.scale(1,1);
ctx.translate(0,0);
ctx.strokeStyle = 'rgba(0,0,0,0)';
ctx.lineCap = 'butt';
ctx.lineJoin = 'miter';
ctx.miterLimit = 4;
ctx.save();
ctx.restore();
ctx.save();
ctx.translate(-178,-203.56851);
ctx.restore();
ctx.save();
ctx.translate(-0.5,0.57940674);
ctx.globalAlpha = 1;
ctx.save();
ctx.fillStyle = "#ffff00";
ctx.strokeStyle = "#000000";
ctx.lineWidth = 5;
ctx.miterLimit = 4;
ctx.globalAlpha = 1;
ctx.beginPath();
ctx.arc(113,111.92059,110,0,6.283185307179586,true);
ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.restore();
ctx.restore();
ctx.save();
ctx.translate(-0.5,0.57940674);
ctx.save();
ctx.fillStyle = "rgba(0, 0, 0, 0)";
ctx.strokeStyle = "#000000";
ctx.lineWidth = 5;
ctx.miterLimit = 4;
ctx.globalAlpha = 1;
ctx.beginPath();
ctx.moveTo(163,173.19968);
ctx.translate(113.0000000000029,173.19967280611772);
ctx.rotate(0);
ctx.scale(1,0.42175754);
ctx.arc(0,0,50,3.4110317058144965e-7,1.0471975511615463,0);
ctx.scale(1,2.3710305214697525);
ctx.rotate(0);
ctx.translate(-113.0000000000029,-173.19967280611772);
ctx.translate(112.9999995,173.19967292786933);
ctx.rotate(0);
ctx.scale(1,0.42175754);
ctx.arc(0,0,50,1.0471975396495925,2.094395113940201,0);
ctx.scale(1,2.3710305214697525);
ctx.rotate(0);
ctx.translate(-112.9999995,-173.19967292786933);
ctx.translate(112.99999999999727,173.1996730496196);
ctx.rotate(0);
ctx.scale(1,0.42175754);
ctx.arc(0,0,50,2.0943951254871433,3.1415923239985117,0);
ctx.scale(1,2.3710305214697525);
ctx.rotate(0);
ctx.translate(-112.99999999999727,-173.1996730496196);
ctx.fill();
ctx.stroke();
ctx.restore();
ctx.restore();
ctx.save();
ctx.translate(-0.5,0.57940674);
ctx.save();
ctx.save();
ctx.fillStyle = "#000000";
ctx.strokeStyle = "rgba(0, 0, 0, 0)";
ctx.lineWidth = 5;
ctx.miterLimit = 4;
ctx.globalAlpha = 1;
ctx.beginPath();
ctx.arc(77.318108,100.36712,20,0,6.283185307179586,true);
ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.restore();
ctx.restore();
ctx.save();
ctx.save();
ctx.fillStyle = "#000000";
ctx.strokeStyle = "rgba(0, 0, 0, 0)";
ctx.lineWidth = 5;
ctx.miterLimit = 4;
ctx.globalAlpha = 1;
ctx.beginPath();
ctx.arc(155.5,100.36712,20,0,6.283185307179586,true);
ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.restore();
ctx.restore();
ctx.restore();
ctx.restore();
};
SVGの実際に図形を描いているのは40行で、 それに対して、生成されたCanvasコードでは100行近くあります。。
今回のSVGは顔、目2つでcircle3つ、口でpath1つだったので、 口以外は、Canvasでarc 3つと translate の組み合わせだけでできると思っていたのですが、 予想以上に複雑になりました。 間に入ってくるctx.rotate(0);
は冗長のような気もします。 簡単な図形は、SVG見ながら自分で書き換えたほうが良さそうです。 何かトレースしてノードだらけの複雑な図形であればこのツール使っても良さそうです。