SVG をラスター画像に変換する方法

SVG 画像をラスター画像に変換したい場合に使うコマンドをまとめている。
変換するのに使える方法はいくつかあるようなので、見つかった方法を全て記載している。
ある方法だと正しくラスタライズされないといった場合でも、他の方法を使えば適切にラスタライズされるので、複数の方法を知っておくのは有用である。
実は[StackOverflow におけるこの議論](https://superuser.com/questions/134679/command-line-application-for-converting-svg-to-png-on-mac-os-x)を見れば済む話なのだが、詳細な内容とかは書かれていないので、ここで改めてまとめることにする。

## Inkscape を使った方法

フリーのベクターソフトウェアでお馴染みの [Inkscape](https://inkscape.org/ja/) には CLI が用意されており、 CLI 単体で SVG を含む様々なフォーマットから/への変換が可能である。

Cairo ライブラリによって描画されており、ベクター画像としては SVG の他に PS,EPS,PDF に対応しているようだが、ラスター画像としては PNG にしか対応していない。

### インストール

[公式サイト](https://inkscape.org/ja/)からダウンロード可能。

多くの Linux ディトリビューションで[パッケージが用意されている](https://pkgs.org/search/?q=inkscape)。
```shell
# Ubuntu / Debian の場合
apt install inkscape
```

Mac / Linux の [Homebrew](https://formulae.brew.sh/formula/inkscape) からも入手できる。
```shell
brew install inkscape
```

### 使い方

単純にファイルを変換する場合 (ファイル形式は拡張子から自動的に判別される)
`-o` オプションを忘れると GUI で Inkscape が起動しようとする。

```shell
inkscape input.svg -o output.png
```

以下のオプションが用意されている (`inkscape --help` から一部を抜粋)

| | |
|:--:|:--|
| `-w` | 出力画像の横幅 |
| `-h` | 出力画像の縦幅 |
| `-d` | 解像度 (デフォルト値は `96`) |
| `-a` | 出力されるビューポート領域 (`x0:y0:x1:y1` の形式) |
| `-b` | 背景色の指定 |

### 備考

出力される PNG 画像には Inksacpe から出力されたことを示すメタ情報が含まれる。

```shell
exiftool -G -args output.png | grep PNG:Software
# -> -PNG:Software=www.inkscape.org
```

これが気に入らないのであれば `exiftool` で消そう。

```shell
exiftool -overwrite_original -PNG:Software= output.png
```

## Librsvg を使った方法

[Librsvg](https://wiki.gnome.org/Projects/LibRsvg) は Cairo を使って SVG を描画するライブラリ。 GNOME プロジェクトの一環である。
ここに含まれている `rsvg-convert` コマンドにより変換ができる。

Inkscape と同じ Cairo で描画されるので、 Inkscape で適切に変換されない画像はおそらくこちらでも変換されない可能性が高く、ラスター画像も PNG にしか対応していない。

### インストール

多くの Linux ディトリビューションで[パッケージが用意されている](https://pkgs.org/search/?q=librsvg)。
```shell
# Ubuntu / Debian の場合
apt install librsvg2
```

Mac / Linux の [Homebrew](https://formulae.brew.sh/formula/librsvg) からも入手できる。
```shell
brew install librsvg
```

### 使い方

単純にファイルを変換する場合 (出力ファイル形式は拡張子から自動的に判別される)
`-o` オプションを忘れると標準出力に出力される。

```shell
rsvg-convert input.svg -o output.png
```

以下のオプションが用意されている (`rsvg-convert --help` から一部を抜粋)

| | |
|:--:|:--|
| `--page-width` | 出力画像の横幅 |
| `--page-height` | 出力画像の縦幅 |
| `--left` | ビューポートの左端 |
| `--top` | ビューポートの上端 |
| `--width` | ビューポートの横幅 |
| `--height` | ビューポートの縦幅 |
| `-d` | 解像度 (デフォルト値は `96`) |
| `-b` | 背景色の指定 |

### 備考

[例の StackOverflow の議論](https://superuser.com/questions/134679/command-line-application-for-converting-svg-to-png-on-mac-os-x)では ImageMagick を使った方法が紹介されているが、バックエンドは Librsvg であり、 Librsvg をインストールする必要がある。
ImageMagick を使う場合は以下のコマンドで変換できる。

```shell
# convert コマンドの方法
convert input.svg output.png
# mogrify コマンドの方法
mogrify input.svg
```

## CairoSVG を使った方法

[CairoSVG](https://cairosvg.org) は Cairo を使って SVG を PNG や PDF に変換する Python ソフトウェア。 [CourtBouillon](https://www.courtbouillon.org) によって開発されている。
CLI には `cairosvg` というコマンドが用意されている。

Inkscape と同じ Cairo で描画されるので、 Inkscape で適切に変換されない画像はおそらくこちらでも変換されない可能性が高く、ラスター画像も PNG にしか対応していない。

### インストール

[PyPI](https://pypi.org/project/CairoSVG/) にあるので Python の `pip` コマンドからインストールできる。
```shell
pip3 install cairosvg
```

### 使い方

単純にファイルを変換する場合 (出力ファイル形式は拡張子から自動的に判別される)
`-o` オプションを忘れると標準出力に出力される。

```shell
cairosvg input.svg -o output.png
```

以下のオプションが用意されている (`cairosvg --help` から一部を抜粋)

| | |
|:--:|:--|
| `--output-width` | 出力画像の横幅 |
| `--output-height` | 出力画像の縦幅 |
| `--width` | ビューポートの横幅 |
| `--height` | ビューポートの縦幅 |
| `-d` | 解像度 |
| `-b` | 背景色の指定 |

## svgexport を使った方法

[svgexport](https://github.com/piqnt/svgexport) とは [Puppeter](https://github.com/puppeteer/puppeteer) (Chrome/Firefox をヘッドレスで起動させる JavaScript ライブラリ) を使った変換ツールである。
つまり、ブラウザで表示される通りに SVG が PNG/JPEG 画像として出力される。ここで使われているブラウザはおそらく Chromium である。

### インストール

[NPM](https://www.npmjs.com/package/svgexport) から入手可能。

```shell
npm install -g svgexort
```

### 使い方

単純にファイルを変換する場合 (出力ファイルの形式は拡張子から自動的に判別される)

```shell
svgexport input.svg output.png
```

以下のようにスペース区切りでオプションが指定できる。省略も可能。
([README](https://github.com/piqnt/svgexport/blob/master/README.md) から抜粋)

```shell
svgexport input.svg output.png [viewport] [imgsize] [crop/pad] [style]
# 例
svgexport input.svg output.png 10:10:50:60 128:128 pad "svg { background-color: #ffff99; }"
```

| | |
|:--:|:--|
| `[viewport]` | 描く領域のビューポートを `L:T:W:H` の形式で指定 |
| `[imgsize]` | 出力画像のサイズを `W:H` の形式で指定 |
| `[crop/pad]` | ビューポートと画像サイズのアスペクト比が合わない場合に<br>切り取るか伸縮させるか |
| `[style]` | スタイルを適用させることができ、<br>ここで背景色とかを指定できる |

### 備考

偶にブラウザプロセスがクラッシュして変換に失敗することがある。
また変換に時間がかかる事があり、タイムアウトで終了する場合もある。

## resvg を使った方法

[resvg](https://github.com/RazrFalcon/resvg) は Rust 製の SVG レンダリングライブラリであり、 CLI から PNG 画像への変換ができる。

### インストール

[GitHub リポジトリ](https://github.com/RazrFalcon/resvg/releases/latest)からダウンロードすることができる。

[crates.io](https://crates.io/crates/resvg) にあるので、 `cargo` コマンドからビルドしてインストールすることもできる。

```shell
cargo install resvg
```

一部の Linux ディトリビューションで[パッケージが用意されている](https://pkgs.org/search/?q=resvg)。
```shell
# Ubuntu 22.04 / Debian 11 の場合
apt install resvg
```

Mac / Linux の [Homebrew](https://formulae.brew.sh/formula/resvg) からも入手できる。
```shell
brew install resvg
```

### 使い方

単純にファイルを変換する場合

```shell
resvg input.svg output.png
```

以下のオプションが用意されている (`resvg --help` から一部を抜粋)

| | |
|:--:|:--|
| `-w` | 出力画像の横幅 |
| `-h` | 出力画像の縦幅 |
| `--dpi` | 解像度 |
| `--background` | 背景色の指定 |

例:
```shell
resvg -w 128 -h 128 input.svg output.png
```

## Apache Batik を使った方法

[Apache Batik](https://xmlgraphics.apache.org/batik/tools/rasterizer.html) は Java で動作する SVG ラスタライザである。 [Apache XML Graphics Project](https://xmlgraphics.apache.org) の一環である。
SVG 画像をラスタライズして PNG/JPEG/TIFF 画像に変換できる。また (ラスタライズしないけど) PDF への変換もできるようだ。

### インストール

[公式サイトから JAR ファイルをダウンロード可能](https://xmlgraphics.apache.org/batik/download.html)なので、 Java 8 以降の JRE/JDK で実行可能である。

多くの Linux ディトリビューションで[パッケージが用意されている](https://pkgs.org/search/?q=batik)。
```shell
# Ubuntu / Debian の場合
apt install batik
```

Mac / Linux の [Homebrew](https://formulae.brew.sh/formula/batik) からも入手できる。
```shell
brew install batik
```

### 使い方

単純にファイルを変換する場合 (ファイル形式は拡張子から自動的に判別される)
`-d` オプションを忘れるとファイル名が自動的に決定される。

```shell
batik-rasterizer -d output.png input.svg
# 或いは
java -jar /path/to/batik-rasterizer.jar -d output.png input.svg
```

以下のオプションが用意されている ([公式ドキュメント](https://xmlgraphics.apache.org/batik/tools/rasterizer.html#using)から一部を抜粋)

| | |
|:--:|:--|
| `-w` | 出力画像の横幅 |
| `-h` | 出力画像の縦幅 |
| `-dpi` | 解像度 |
| `-a` | 出力されるビューポート領域 (`L,T,W,H` の形式) |
| `-bg` | 背景色の指定 (`a.r.g.b` の形式で、各々 0-255 の値をとる) |

## wkhtmltopdf を使った方法

[wkhtmltopdf](https://wkhtmltopdf.org) は Qt WebKit レンダリングエンジンを使って HTML を PDF に変換する CLI ツールである。
同梱の `wkhtmltoimage` コマンドによりラスター画像への変換ができる。

**[リポジトリ](https://github.com/wkhtmltopdf/wkhtmltopdf)は2023年1月にアーカイブされているので、更新はないという意味で使用を控えた方が良さそう。**

背景が透明な SVG 画像でも、生成される画像の背景は白くなる。

### インストール

[公式サイト](https://wkhtmltopdf.org/downloads.html)からダウンロード可能。

多くの Linux ディトリビューションで[パッケージが用意されている](https://pkgs.org/search/?q=wkhtmltopdf)。
```shell
# Ubuntu / Debian の場合
apt install wkhtmltopdf
```

Mac / Linux の [Homebrew](https://formulae.brew.sh/formula/wkhtmltopdf) からも入手できる。
```shell
brew install wkhtmltopdf
```

### 使い方

単純にファイルを変換する場合
出力ファイル形式は拡張子から自動的に判別されるが、そもそも対応している出力ファイル形式はドキュメントに記載されていない。

```shell
wkhtmltoimage input.svg output.png
```

以下のオプションが用意されている (`wkhtmltoimage -H` から一部を抜粋)

| | |
|:--:|:--|
| `--width` | 出力画像の横幅 |
| `--height` | 出力画像の縦幅 |
| `--crop-x` | ビューポートの左端 |
| `--crop-y` | ビューポートの上端 |
| `--crop-w` | ビューポートの横幅 |
| `--crop-h` | ビューポートの縦幅 |

## QuickLook を使った方法

macOS 標準の機能である QuickLook のサムネイル画像として出力する方法である。

サムネイル画像を保存する機能なだけなので、使い勝手はあまり良くないかもしれない。
具体的には以下の点を注意しなければならない。
* 背景が透明であっても、白い背景になる。
* 画像のサイズは正方形になりそう。
* サイズを明示的に指定しないと意図しないサイズの画像になる。
* 画像が出力されるディレクトリの設定はできるが、ファイル名までは指定できない。
	* `input.svg` なら `input.svg.png` になってしまう。

### 使い方

```shell
qlmanage -t -s 1024 -o /path/to/output/dir input.svg
```

`man qlmanage` によれば、上記で指定したオプションには以下の意味がある。

* `-t` はサムネイル画像であることを表す。
* `-s` は画像の一辺のサイズを指定する。
* `-o` は出力先ディレクトリを指定する。