SVG.NETを使いSVGファイルを作成してみた


[https://github.com/vvvv/SVG](https://github.com/vvvv/SVG) で公開されているSVG.NETを使って、SVGファイルを作成してみました。

使う言語はC#です。


## 準備

Nugetパッケージでsvgをインストール。

>Svg  作成者: davescriven,jvenema,owaits,ddpruitt,Ralf1108,Tebjan Halm,and others
>Open source library to load/save and render SVG vector graphics.

System.Drawingが必要なので、プロジェクトの参照設定に`System.Drawing`も追加します。

なお、ターゲットは、.NET Framework限定です。.NET Coreには対応していません。
.NET Core3.0になれば、公開されているソースをすこし変更すれば対応が可能だと思われますが…
でもその場合でも、Windows限定になるのかなー？

## 簡単な使い方

### using

まずは、Svgを`using`します。

```cs
using Svg;
```

### SvgDocumentのインスタンスを生成

次に、SvgDocumentのインスタンスを生成。

```cs
var svgDoc = new SvgDocument {
    Width = 500,
    Height = 500
};
```

インスタンス生成時には、幅と高さを指定します。

### ViewBoxの指定

```cs
svgDoc.ViewBox = new SvgViewBox(-250, -250, 500, 500);
```

最初の２つの引数は、x,y座標の開始位置、残りの２つは、幅と高さ。
実際のSvgの領域と座標系を別に指定できるってことですね。

### Svgのg要素を追加

グループ化するためのコンテナであるg要素を追加。

```cs
var group = new SvgGroup();
svgDoc.Children.Add(group);
```

これで、svgタグの直下にg要素を生成できます。

### 図形の描画

以下は、Circleを描画するコードです。

```cs
group.Children.Add(new SvgCircle {
    Radius = 100,
    Fill = new SvgColourServer(Color.Red),
    Stroke = new SvgColourServer(Color.Black),
    StrokeWidth = 2
});
```

その他、`SvgRectangle`, `SvgLine`, `SvgText`, `SvgPolyline`, `SvgPath`などもあるみたい。

### ファイルに出力

svgファイルを保存するには、Writeメソッドを利用します。


```cs
svgDoc.Write("sample.svg");
```

## 作成したサンプルコード（１）

SvgCircle、SvgLine、SvgRectangle を使ったサンプルです。

```cs
using Svg;
using System.Drawing;

namespace SvgSample {
    class Program {
        static void Main(string[] args) {
            var svgDoc = new SvgDocument {
                Width = 500,
                Height = 500
            };

            svgDoc.ViewBox = new SvgViewBox(-250, -250, 500, 500);

            var group = new SvgGroup();
            svgDoc.Children.Add(group);

            group.Children.Add(new SvgCircle {
                Radius = 100,
                Fill = new SvgColourServer(Color.FromArgb(43, 138, 190)),
                Stroke = new SvgColourServer(Color.FromArgb(32, 101, 139)),
                StrokeWidth = 2
            });

            group.Children.Add(new SvgLine() {
                StartX = 0,
                StartY = -120,
                EndX = 0,
                EndY = 120,
                Stroke = new SvgColourServer(Color.LightGray),
                StrokeWidth = 3
            });

            group.Children.Add(new SvgRectangle() {
                X = -200,
                Y = -160,
                Width = 80,
                Height = 60,
                Fill = new SvgColourServer(Color.FromArgb(0, 170, 180))
            });

            var group2 = new SvgGroup();
            group.Children.Add(group2);
            for (int x = -100; x < 0; x += 5) {
                group2.Children.Add(new SvgRectangle() {
                    X = x,
                    Y = -210,
                    Width = 3,
                    Height = 5,
                    Fill = new SvgColourServer(Color.DarkGray)
                });
            }
            svgDoc.Write("sample.svg");
        }
    }
}
```


### 作成されたSVGファイル
```html
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg x="0" y="0" width="500" height="500" overflow="inherit" viewBox="-250, -250, 500, 500" preserveAspectRatio="xMidYMid" font-size="0" xml:space="default" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xml="http://www.w3.org/XML/1998/namespace" version="1.1">
  <g xml:space="default">
    <circle r="100" stroke="#20658B" stroke-width="2" xml:space="default" style="fill:#2B8ABE;" />
    <line x1="0" y1="-120" x2="0" y2="120" stroke="#D3D3D3" stroke-width="3" xml:space="default" />
    <rect x="-200" y="-160" width="80" height="60" xml:space="default" style="fill:#00AAB4;" />
    <g xml:space="default">
      <rect x="-100" y="-210" width="3" height="5" xml:space="default" style="fill:#A9A9A9;" />
      <rect x="-95" y="-210" width="3" height="5" xml:space="default" style="fill:#A9A9A9;" />
      <rect x="-90" y="-210" width="3" height="5" xml:space="default" style="fill:#A9A9A9;" />
      <rect x="-85" y="-210" width="3" height="5" xml:space="default" style="fill:#A9A9A9;" />
      <rect x="-80" y="-210" width="3" height="5" xml:space="default" style="fill:#A9A9A9;" />
      <rect x="-75" y="-210" width="3" height="5" xml:space="default" style="fill:#A9A9A9;" />
      <rect x="-70" y="-210" width="3" height="5" xml:space="default" style="fill:#A9A9A9;" />
      <rect x="-65" y="-210" width="3" height="5" xml:space="default" style="fill:#A9A9A9;" />
      <rect x="-60" y="-210" width="3" height="5" xml:space="default" style="fill:#A9A9A9;" />
      <rect x="-55" y="-210" width="3" height="5" xml:space="default" style="fill:#A9A9A9;" />
      <rect x="-50" y="-210" width="3" height="5" xml:space="default" style="fill:#A9A9A9;" />
      <rect x="-45" y="-210" width="3" height="5" xml:space="default" style="fill:#A9A9A9;" />
      <rect x="-40" y="-210" width="3" height="5" xml:space="default" style="fill:#A9A9A9;" />
      <rect x="-35" y="-210" width="3" height="5" xml:space="default" style="fill:#A9A9A9;" />
      <rect x="-30" y="-210" width="3" height="5" xml:space="default" style="fill:#A9A9A9;" />
      <rect x="-25" y="-210" width="3" height="5" xml:space="default" style="fill:#A9A9A9;" />
      <rect x="-20" y="-210" width="3" height="5" xml:space="default" style="fill:#A9A9A9;" />
      <rect x="-15" y="-210" width="3" height="5" xml:space="default" style="fill:#A9A9A9;" />
      <rect x="-10" y="-210" width="3" height="5" xml:space="default" style="fill:#A9A9A9;" />
      <rect x="-5" y="-210" width="3" height="5" xml:space="default" style="fill:#A9A9A9;" />
    </g>
  </g>
</svg>
```

### 作成された図形

![スクリーンショット 2018-10-27 16.21.35.png](https://qiita-image-store.s3.amazonaws.com/0/29415/ead75f3d-5c47-3c31-ac47-ad2c9772164c.png "スクリーンショット 2018-10-27 16.21.35.png")



## 作成したサンプルコード（２）

SvgPath と SvgText も使ってみました。

```cs
var svgDoc = new SvgDocument {
    Width = 500,
    Height = 500
};

svgDoc.ViewBox = new SvgViewBox(0, 0, 250, 250);

var group = new SvgGroup();
svgDoc.Children.Add(group);

var seglist = SvgPathBuilder.Parse("M 10,60 L 30,10 90,10 110,60 z");

group.Children.Add(new SvgPath {
    StrokeWidth = 1,
    Fill = new SvgColourServer(Color.FromArgb(152, 225, 125)),
    Stroke = new SvgColourServer(Color.DarkGray),
    PathData = seglist
});


group.Children.Add(new SvgText {
    Nodes = { new SvgContentNode {  Content = "Sample" } },
    X = { 30 },
    Y = { 50 },
    Fill = new SvgColourServer(Color.White),
    FontSize = 18,
    FontFamily = "sans-serif"
});

svgDoc.Write("sample2.svg");
```


### 作成された図形

![スクリーンショット 2018-10-27 16.24.28.png](https://qiita-image-store.s3.amazonaws.com/0/29415/224287ab-bbb7-96f2-0bf2-71c0f88543ca.png "スクリーンショット 2018-10-27 16.24.28.png")


---

このSVG.NETは、サーバー側で、SVGファイルを作成したいといった時に使えそうです。


※ ソースコードは、[GitHub](
https://github.com/gushwell/CSharpAlgorithmCollection2)で公開しています。