Pythonで写真がドット絵へ変換！ノベルゲーム背景のために。

Unityで作っているノベルゲームのために、いい背景のように面白い方法を調べました。Pythonのライブラリと小さいスクリプト、写真からいいドット絵風に画像ができます。

---

# なぜ写真から？

ノベルゲームの中で、そんな仕方は見たことある。一番人気な例はきっと「ひぐらしのなく頃に」ですよね。

ゼロから絵を書かないように、撮った写真から背景の作りがもうちょっと簡単になるだろうと思いました。写真編集ソフトの中でフィルタ－を使ったら、絵を似るように修整ができるですが、いい結果を目指すは難しそうね。

とりあえず、僕は絵を書くの腕が悪いのでそんな技術を思い出した。日本に住んでたときから取った写真が多いから背景で使えませんかっと思いました。

---

# なぜドット絵へ？

最初、ドット絵の利用はもちろん、レトロな感じですよね。ゲームのUIもうドット絵でやってみたいっと思った、いいチャレンジですから。

ゲーム美術表現の選択のさらに、リアルからドット絵へ変換にはメリットが多い。

たとえば、、、

* 有名なブランドのロゴや名前がちょっとだけ認めるので、商標権の問題が無くなる。
* 通りや内部でポスターや広告がもう読めないので、内容は心配しない。
* 人々の顔はもう見えません。
* ドット絵で粗いになるので、元写真の修整をしたい場合はやりすぎないでもいいです。

---

# 変換の先に修整

リアル写真を使っても、フィクションを感じるためにゲームの世界は本世界とちょっと違っています。

会社の名前とロゴとか、それとも物の色とか、変換の先に本物よりちょっと変えましょうかって思いました。こういう、ゲームの世界は強化されます。

![bus_original.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1564614/38169ade-ba75-8be3-ad81-788d006a6268.jpeg)

この記事のために、この高速バスの写真を例として使いましょう。一歩一歩行って見ましょう。

### ステップ１・ カラーパレットを下げる

ドット絵の変換と16色だけのパレットが欲しいんだから、始めに無駄な色を消しましょう。この写真には、車内のオレンジ光があって、バスは白とピンク、空は真っ黒、道路はちょっとグレイです。

その他、乗降口の向こうから緑の光がします。ここだけの緑色なので、消したほうがいい。

![bus_palette.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1564614/abee45e7-47ef-085e-b101-471d9c44527d.jpeg)

### ステップ２・ 色を変わる、元ブランドを消して

後は、ピンク色でバスが認めやすいから車体の色が変わりたい。もちろん、ブランドの名前もう消しならければならない。ロゴは車体の表と階段の上に書いたですね。

![nightbus_colorbrand.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1564614/462b8a51-d0fe-b2bb-9f3b-d0c53cbd98be.jpeg)

### ステップ３・ 新しいロゴを使う

元ブランドの代わりに、偽会社を作りました。高速バス会社は鳥の名前と形をよく使ってるから、同じくしませんか？「ときエクスプレス」になっちゃった。

ロゴは車体にちゃんと印刷されなそうだが、大丈夫だと思います。

![nightbus_newbrand.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1564614/91605734-27fa-1aaa-dc78-89982a8a850b.jpeg)

さあ、写真が準備しておいた。

---

# ドット絵へ変換

ついに変換の話にきました。ドット絵だったら色んな方法があるんだけど、この間はすごいPythonライブラリを見つけました。「[Super Pyxelate](https://github.com/sedthh/pyxelate)」のおかげで写真からドット絵までの変換ができます。

ライブラリの使い方はそんなに難しいくないだと思います。次の簡単なPythonスクリプトで使います。

```python:スクリプト
import argparse
from pathlib import Path

from skimage import io
from pyxelate import Pyx
from PIL import Image

parser = argparse.ArgumentParser(description="写真からドット絵変換")
parser.add_argument("filename", help="変換欲しいのファイルネーム")
args = parser.parse_args()

# 画像の幅は1920px似内が欲しいなので、大きい過ぎる場合は変更します
with Image.open(args.filename) as im:
    if im.width > 1920:
        factor = 1920 / im.width
        im_resized = im.resize((int(im.width * factor), int(im.height * factor)))
        im_resized.save(args.filename, quality=100, subsampling=0)

image = io.imread(args.filename)

# ドット絵の変換中で、画像は6倍の小さになる
downsample_by = 6
# ドット絵は16色の中で欲しい
palette = 16

# ドット絵の変換の後で、元のサイズへ戻るようにupscaleはfactorと同じです
pyx = Pyx(factor=downsample_by, upscale=downsample_by, palette=palette)

# ここはPyxelateがカラーパレットを考えます
pyx.fit(image)

# ドット絵へ変換します
new_image = pyx.transform(image)

# 結果の画像をセーブ
name = Path(args.filename).stem
io.imsave(f"{name}_pixel.png", new_image)
```

### ステップ４・変換

さて、スクリプトの執行あとで、ついにドット絵の風な画像が出てきました。

![nightbus_pixel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1564614/6995b73b-b220-3a19-6a96-3440db5187ac.png)

### ステップ５・詳細を磨く

結果の画像は喜ぶんですが、まだ完璧じゃありません。道路に影はバラバラ、会社の名前とロゴはよく読めない、階段の段は認めない、あっちこっちにはピクセルの汚れがあります。

画像のドットは1ピクセルに戻るように6倍小さなを変更して、そしてドット絵画像処理ソフトで磨くしましょう。

![nightbus_pixel_retouched.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1564614/91e74f0f-88c2-04eb-6edb-57f67de38332.png)

これで完了しました。ドット絵の画像を磨くことは微妙な過程ですが、これでいいんじゃない？

とにかくこの方法のおかげで、自分のノベルゲームがちゃんと作り続けます。

---

読んでありがたいです。そのトピックで話したいなら、ツイッターは[@komanakun](https://twitter.com/komanakun)、Wantedlyは[こちら](https://www.wantedly.com/id/michaelhubert)です。