Pythonでsvgファイルをpng/icoに変換する


## はじめに

* デザインとかフロントのことはよくわからない。
* とある作業中、favicon 用に ico ファイルが必要だけど、フロントの人に svg しかもらっていなかった。
* 外部サイトで変換ツールがあるのは知っているけど一応仕事のファイルなので使いたくない。
* わざわざ ico 作ってって頼むのもあれだし、とりあえず手元で手っ取り早くやるために Python でやる方法を調べてみた。
* この方法が妥当なのかとかはわからないけど、とりあえずできることはできる。

## 環境

* Python 3.6.6


## How to do it


軽くググってみたら、svg -> png -> ico の順に変換している例が多かった。


### svg -> png

svg -> png の変換は [cairosvg](https://cairosvg.org/) ってやつを使えばできるらしい。

インストール

```
$ pip install cairosvg
```

実行ファイルが入っているようなのでそのまま実行。

そしてエラー...

```
$ cairosvg sample.svg -o sample.png
Traceback (most recent call last):
  File "/Users/tommarute/miniconda3/envs/py366/bin/cairosvg", line 6, in <module>
    from cairosvg.__main__ import main
  File "/Users/tommarute/miniconda3/envs/py366/lib/python3.6/site-packages/cairosvg/__init__.py", line 42, in <module>
    from . import surface  # noqa isort:skip
  File "/Users/tommarute/miniconda3/envs/py366/lib/python3.6/site-packages/cairosvg/surface.py", line 28, in <module>
    from .defs import (
  File "/Users/tommarute/miniconda3/envs/py366/lib/python3.6/site-packages/cairosvg/defs.py", line 24, in <module>
    from .bounding_box import calculate_bounding_box, is_non_empty_bounding_box
  File "/Users/tommarute/miniconda3/envs/py366/lib/python3.6/site-packages/cairosvg/bounding_box.py", line 26, in <module>
    from .features import match_features
  File "/Users/tommarute/miniconda3/envs/py366/lib/python3.6/site-packages/cairosvg/features.py", line 25, in <module>
    LOCALE = locale.getdefaultlocale()[0] or ''
  File "/Users/tommarute/miniconda3/envs/py366/lib/python3.6/locale.py", line 562, in getdefaultlocale
    return _parse_localename(localename)
  File "/Users/tommarute/miniconda3/envs/py366/lib/python3.6/locale.py", line 490, in _parse_localename
    raise ValueError('unknown locale: %s' % localename)
ValueError: unknown locale: UTF-8
```

なにやら locale が unknown らしい

指定してみる

```
$ LC_CTYPE="ja_JP.UTF-8" cairosvg sample.svg -o sample.png
```

いけました。

```
$ ls -ltr
total 16
-rw-r--r--  1 tommarute  user   348 Nov 17 22:15 sample.svg
-rw-r--r--  1 tommarute  user  1473 Nov 17 22:16 sample.png
```

### png -> ico

png -> ico は [pillow](https://pillow.readthedocs.io/en/stable/) でいけるらしい。

インストール

```
$ pip install pillow
```

こっちは実行ファイルはないのでライブラリとして使う。


```ipython
In [1]: from PIL import Image

In [2]: fn = r'sample.png'

In [3]: img = Image.open(fn)

In [4]: img.save('favicon.ico')

In [5]:

```

いけました。

```
$ ls -ltr
total 48
-rw-r--r--  1 tommarute  user    348 Nov 17 22:15 sample.svg
-rw-r--r--  1 tommarute  user   1473 Nov 17 22:16 sample.png
-rw-r--r--  1 tommarute  user  12993 Nov 17 22:20 favicon.ico
```

## 最後に

このままじゃちょっとあれなので多少マシなスクリプトにしてみよう。

```python
import sys
import os
os.environ['LC_CTYPE'] = "ja_JP.UTF-8"
import cairosvg
from PIL import Image


def run(svg, ico):
    print(f'svg = {svg}')
    print(f'ico = {ico}')
    png = f'{svg}.png'
    cairosvg.svg2png(url=svg, write_to=png)
    img = Image.open(png)
    img.save(ico)
    print('Deleting temporary png file.')
    os.unlink(png)
    print('svg2ico has finished normally.')

def main():
    args = sys.argv
    run(args[1], args[2])


if __name__ == '__main__':
    main()


```

おしまい

## 参考

* https://stackoverflow.com/questions/45507/is-there-a-python-library-for-generating-ico-files