ImageMagickで画像を切り抜いて連結する


# やりたかったこと
こんな感じで並んでいるローグライク用のモンスター画像を
![zombie_src_2x.png](https://qiita-image-store.s3.amazonaws.com/0/43772/9842f720-ccf5-e58d-5e5f-f55c11bf64ef.png "zombie_src_2x.png")

↓↓↓
こういう並びに変えたかったのですが……

![zombie_2x.png](https://qiita-image-store.s3.amazonaws.com/0/43772/4fdd3573-98ea-0310-d51c-66f6ea597f57.png "zombie_2x.png")

これだけのキャラクターの画像をすべて手作業で処理するのはかなり大変……。
![all_x2.png](https://qiita-image-store.s3.amazonaws.com/0/43772/0d52785f-cd93-2d6d-3d24-d64f19e7810f.png "all_x2.png")

なので、スクリプトで自動化できないかと調べたところ、ImageMagickを使うのがよさげでした。

# ImageMagickのインストール
Mac環境なのでMacPorts経由でインストールしました。

* [macにImageMagickをインストール！](http://naganegi0505.hatenablog.com/entry/2013/01/28/173302)


Windows環境なら、こちらを参考にインストーラーを使うと簡単にインストールできそう。

* [ImageMagick インストール](http://windows.server-manual.com/windows_imagemagick.html)

# やり方
## 手順
以下の手順で画像を加工することにしました

1. 画像を切り抜いて、1つのキャラ画像に分ける
2. 切り抜いたキャラ画像を連結する

## 画像の切り抜き
画像の切り抜きには `-crop` オプションを使います。

```bash:bash
  convert [入力ファイル] -crop '[幅]x[高さ]+[左上X座標]+[左上Y座標]' [出力ファイル]
```

たとえば、input.png 画像の(x,y)=(10,20)を左上座標として、32x32のサイズで切り抜く場合は、以下のコマンドとなります。

```bash:bash
  convert input.png -crop '32x32+10+20' output.png
```

これを踏まえてゾンビ画像を1パーツごとに切り出すPythonスクリプト
![zombie_src_2x.png](https://qiita-image-store.s3.amazonaws.com/0/43772/9842f720-ccf5-e58d-5e5f-f55c11bf64ef.png "zombie_src_2x.png")

```python:crop.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os

# ■まずは画像を切り抜く
# 切り抜きサイズ
SIZE = 16
# 入力ファイル
INPUT = "all.png"

# zombieの開始座標
x = 80
y = 80
for i in range(0, 15):
	# 5x3で並んでいる
	ox = (i / 3) * SIZE
	oy = (i % 3) * SIZE
	ox += x
	oy += y

	# 出力ファイル (tmpフォルダに出力)
	out = "tmp/%d.png"%i

	# コマンド文字列作成
	cmd = "/opt/local/bin/convert %s -crop '%dx%d+%d+%d' %s"%(INPUT, SIZE, SIZE, ox, oy, out)
	print cmd
	# 実行
	os.system(cmd);
```

これは、all.png からキャラを切り抜いて、tmpフォルダに 0〜14.png として出力するスクリプトとなります。これで個別に切り出すことができました。

![crop.png](https://qiita-image-store.s3.amazonaws.com/0/43772/f4cac747-a7ee-6dab-e45c-4a1069ee09aa.png "crop.png")

## 画像を連結する
次に切り出した画像を連結します。
切り出しには `+append` オプションを使用します。

```bash:bash
  convert +append [入力ファイル1] [入力ファイル2] [...] [出力ファイル]
```

たとえば、1.png 2.png 3.png を連結して、out.png に出力するコマンドは以下のようになります。

```bash:bash
  convert +append 1.png 2.png 3.png out.png
```

これを踏まえて切り出した画像を連結するPythonスクリプトがこちら。

```python:append.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os

# ■画像を結合
# 横につなげる
cmd = "/opt/local/bin/convert +append "
for i in range(0, 15):
	# 入力ファイル
	inFile = "tmp/%d.png"%i
	# コマンド文字列に連結
	cmd += inFile + " "

# 出力ファイル名を設定
cmd += "zombie.png"
print cmd

# 実行
os.system(cmd)
```

tmpフォルダ内にある 0〜14.png を「zombie.png」に出力するスクリプトです。これにより、以下のように画像が連結できました。

![zombie_2x.png](https://qiita-image-store.s3.amazonaws.com/0/43772/4fdd3573-98ea-0310-d51c-66f6ea597f57.png "zombie_2x.png")

あとはこのスクリプトを改造すれば、すべてのキャラを簡単に切り抜けそうです。

# おまけ
## ドット絵をぼやけないように拡大する
ドット絵のゲームの場合、ドット感を出すために低解像度でデータを用意して、実際のゲーム上では拡大して使うことがあります。その場合、普通に拡大するとぼやけた感じになってしまいます。

たとえば、これは32x32のドット絵ですが、
![player32x32.png](https://qiita-image-store.s3.amazonaws.com/0/43772/b346a8f1-ed09-98f8-39c6-08e8a8590fd7.png "player32x32.png")

これを96x96にそのまま拡大するとぼやけた感じになってしまいます。
![player96x96.png](https://qiita-image-store.s3.amazonaws.com/0/43772/cbc4e8e5-96d1-842b-4bed-df9b06e9d367.png "player96x96.png")

そこで、ピクセル比を固定したまま拡大にする必要があります。
![player96x96point.png](https://qiita-image-store.s3.amazonaws.com/0/43772/10b0491d-9d5e-331b-3c95-51241c364f85.png "player96x96point.png")

ImageMagickでこの変換を行うには `-filter box` オプションを指定します。

```bash:bash
  convert -filter box -resize [倍率]% [入力ファイル] [出力ファイル]
```

倍率は100%基準値となります。たとえば、画像 input.png を2倍のサイズにしたい場合は、以下のコマンドを実行します。

```bash:bash
  convert -filter box -resize 200% input.png output.png
```

以下はPythonスクリプトを使って、ピクセル比固定で、画像を2倍にして出力する方法です。

```python:scale.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os

# 入力ファイル
INPUT = "zombie.png"
# 出力ファイル
OUTPUT = "zombie_2x.png"
# 2倍にする
SCALE = 2

# コマンド文字列作成
cmd = "/opt/local/bin/convert -filter box -resize %d%% %s %s"%(SCALE*100, INPUT, OUTPUT)
print cmd

# 実行
os.system(cmd)
```

zombie.png を 2倍に拡大し、 zombie_2x.png として出力するスクリプトとなります。

## モンスター画像
今回切り出したモンスター画像はこちらからお借りしました。

* [DENZI部屋　（フリー素材置き場）](http://www3.wind.ne.jp/DENZI/diary/)

ローグライクに使えるいい感じの画像がたくさんあって、とてもよいです。

## 透過色を指定して透過画像を作る

`-transparent` オプションを指定すると透過色を指定して出力できます。

```bash:bash
  convert -transparent '#RRGGBB' [入力ファイル] [出力ファイル]
```

たとえば今回使ったモンスター画像の背景色は `#476c6c` なので、

```bash:bash
  convert -transparent '#476c6c' zombie.png zombie_alpha.png
```

とすると、透過した画像 zombie_alpha.png を作ることができます。