SVG

SVGとは

SVG(Scalable Vector Graphics)は比較的新しいベクトル形式の画像フォーマットです。Adobe IllustratorやオープンソースのInkscapeなどで作成できるほか,テキストファイルですので,Windowsの「メモ帳」などのテキストエディタでも簡単に作れます。単独のファイルにできるほか,HTML5の中にインラインで書くこともできます。

SVGはほとんどの新しいブラウザで使えます。IEだけは対応が遅かったのですが,やっとIE 9で使えるようになりました。モバイル環境でも問題なく使えるはずです(例外:Android 3未満,Opera mini,ガラケー)。

HTML5のファイルに直接(インラインで)書き込む例

単位のない数値はピクセル単位になります。座標は,左上隅が原点 (0,0) で,右向きにx座標,下向きにy座標が増えます。

青い まる を描いた。

<p>青い
<svg width="50" height="50">
  <circle cx="25" cy="25" r="22" fill="#9999FF" stroke="black" stroke-width="2" />
  <text x="25" y="30" text-anchor="middle">まる</text>
</svg>
を描いた。</p>

別ファイルに保存する例(svg)

テキストエディタ(「メモ帳」など)で次のように書いて,maru.svg というファイル名で保存します。文字コードはutf-8にします。インラインで書き込む方法と違って,svg の属性として xmlns="http://www.w3.org/2000/svg" を書かないとうまく認識しないようです。また,文字は svg または text の属性として style="font-size:16px" のようなことを書いておかないと表示されないことがあるようです。

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="50" height="50" style="font-size:16px">
  <circle cx="25" cy="25" r="22" fill="#9999FF" stroke="black" stroke-width="2" />
  <text x="25" y="30" text-anchor="middle">まる</text>
</svg>

このようなファイルは img タグで画像として読み込むことができます。

青いまるを描いた。

<p>青い<img src="maru.svg" alt="まる">を描いた。</p>

svgが読み込めない場合は,.htaccess というファイルに次のように書いてみてください:

AddType image/svg+xml svg
AddType image/svg+xml svgz

別ファイルに保存する例(svgz)

svgファイルはgzipで圧縮することもできます。圧縮後の拡張子は svgz にします。LinuxやMacのコマンドで次のように打ち込めば maru.svg から maru.svgz が作れます。

gzip -cfq9 maru.svg >maru.svgz

青いまるを描いた。

<p>青い<img src="maru.svgz" alt="まる">を描いた。</p>

svgが読み込めてsvgzが読み込めない場合は,.htaccess というファイルに次のように書いてみてください:

AddEncoding gzip svgz

ただしsvgzファイルはブラウザで単独で開けるとは限りません。また,サーバとブラウザが圧縮に対応していれば,圧縮は自動的にされるはずなので,svgのままでもネットワーク負荷は増えないはずです。

上の例に示したように,円を描くのは <circl cx="中心のx" cy="中心のy" r="半径" /> です。線の色は stroke,内部の色は fill,線の幅は stroke-width で指定します。

<svg width="200" height="100">
  <circle cx="100" cy="50" r="40" stroke="black" fill="none" />
</svg>

省略した値は 0 になります。ただし,半径を 0 にすると,描かれません。

四角形

四角形を描くのは <rect x="左上隅のx" y="左上隅のy" width="幅" height="高さ" /> です。線の色は stroke,内部の色は fill,線の幅は stroke-width で指定します。

<svg width="200" height="100">
  <rect x="20" y="20" width="160" height="80" stroke="black" fill="none" />
</svg>

省略した値は 0 になります。ただし,幅や高さを 0 にすると,描かれません。

点を描きたいときは小さい四角形を塗りつぶします:

<svg width="200" height="100">
  <rect x="98" y="48" width="4" height="4" fill="black" />
</svg>

パス

今までPostScriptで描いていたベクトルグラフィックはそのままSVGに移行できます。しかも,命令はずっと簡単になります。

PostScriptSVG
絶対移動100 200 movetoM 100 200
相対移動100 200 rmovetom 100 200
絶対線分100 200 linetoL 100 200
相対線分100 200 rlinetol 100 200
絶対曲線1 2 3 4 5 6 curvetoC 1 2 3 4 5 6
相対曲線1 2 3 4 5 6 rcurvetoc 1 2 3 4 5 6
パスを閉じるclosepathZ

これらの命令を <svg> ... </svg> の中の <path d="..." /> の中に書きます。

座標は繰り返すことができます。例えば L 10 20 L 30 40L 10 20 30 40 でもかまいません。

下の例では,位置が見やすいように,背景に黄色い長方形(rect)を描きました。

<svg width="200" height="100">
  <rect width="200" height="100" fill="yellow" />
  <path d="M 20 10 L 180 10 100 90" fill="none" stroke="black" stroke-width="5" />
</svg>

C言語によるSVGの生成

SVGを生成するための簡単なC言語のライブラリです。使い方の例はこの下にあります。

#include <stdio.h>
static double ymax;

void plot_start(int x, int y)  /* プロット開始 */
{
    printf("<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"%d\" height=\"%d\">\n", x, y);
    printf("<path d=\"");
    ymax = y;
}

void plot_end(int close)  /* プロット終了 */
{
    if (close) printf("Z");
    printf("\" fill=\"none\" stroke=\"black\" />\n");
    printf("</svg>\n");
}

void move(double x, double y)  /* ペンアップで移動 */
{
    printf("M %g %g ", x, ymax - y);
}

void move_rel(double dx, double dy)  /* 同上 (相対座標) */
{
    printf("m %g %g ", dx, -dy);
}

void draw(double x, double y)  /* ペンダウンで移動 */
{
    printf("L %g %g ", x, ymax - y);
}

void draw_rel(double dx, double dy)  /* 同上 (相対座標) */
{
    printf("l %g %g ", dx, -dy);
}

上のコードに続けて,次のように打ち込んでみましょう。

#include <math.h>

int main(void)
{
    int i;
    double theta, x, y;

    plot_start(300, 300);  /* x, yの最大値(整数)を与えてプロット開始。最小値は0, 0(左下隅) */
    for (i = 0; i < 5; i++) {
        theta = 2 * M_PI * i / 5;
        x = 150 + 140 * cos(theta);
        y = 150 + 140 * sin(theta);
        if (i == 0) {
            move(x, y);
        } else {
            draw(x, y);
        }
    }
    plot_end(1);  /* プロット終了。1なら閉じる(出発点に戻る線を引く)。0なら閉じない */
    return 0;
}

これ全体を例えば test.c という名前で保存し,コンパイルして,実行し,出力をリダイレクトしてSVGファイルを作ります:

gcc test.c
./a.out >test.svg

test.svg というファイルができるので,Webブラウザで開いてみましょう。5角形が出力されたはずです。

向きを正しくするにはどうすればいいでしょうか。星形にするには?

参考


Last modified: