Xcodeで使うiOS用のRetina画像を生成するツール

### 概要

iOSの開発で、Retina画像が必要になることが多いと思います。
知っている方も多いと思いますが、Retina画像は端末の解像度に応じて「`@x1`」「`@x2`」「`@x3`」をファイル名の末尾に付けた3種類が必要です。
解像度を変えた画像自体は Photoshop のバッチ機能やIllustratorのアセットで作れるのですが、ファイル名の変更が意外と面倒です。

そこで、解像度を変えつつファイル名も良いように生成してくれる簡単なツールを作ってみたら思いのほか便利だったので、ここに公開します。

## 前提条件

このツールは、1倍、2倍、3倍の画像を、6倍の画像からダウンコンバートして作ります(2と3の最小公倍数が6だからですね)。
つまり、実際には使われない6倍画像を用意する必要があります。下記の[6倍画像の作り方のコツ](#6倍画像の作り方のコツ)を参考にしてください。

元画像はあらかじめ、ディレクトリ(フォルダー)にまとめて入れておきます。
生成される画像を入れるディレクトリも、あらかじめ作っておきます。
このツールは10枚以上とかの画像を変換することを想定しているので、このようなディレクトリ内のファイルを一括処理する仕様にしています。

処理できる画像形式は、png と jpeg だけです。

あと、すみません、実行にはJavaが必要です。Javaが入っていない人は、[OpenJDK](https://openjdk.java.net/)とかからインストールしてください。
Javaなので、Windowsでもmacでも動作します。

GUIではないので、コマンドラインでの操作が必要です。

## 実行ファイル

[RetinaFraction6.jar](https://drive.google.com/file/d/1oynnYt9SFeyeAl8da2OWhwWzhiRmwGQk/view?usp=sharing)

## 実行方法

実行はコマンドラインで行います。
Windowsなら「cmd (コマンドプロンプト)」、macなら「ターミナル」を起動し、RetinaFraction6.jar を置いたディレクトリに移動して

```shell
java -jar RetinaFraction6.jar ソースディレクトリ名 書き出しディレクトリ名
```

と入力します。
(ディレクトリ名は、[cmd](https://www.google.com/search?ei=C8IJXePSDYuMvQSq97KQBA&q=cmd+%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80+%E3%83%89%E3%83%A9%E3%83%83%E3%82%B0&oq=cmd+%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80+%E3%83%89%E3%83%A9%E3%83%83%E3%82%B0&gs_l=psy-ab.3...180651.181149..181854...0.0..0.91.251.3......0....1..gws-wiz.-93yQ_ITVvU) や [ターミナル](https://www.google.com/search?ei=TcAJXf7WIY79rQHKjo2oDQ&q=mac+%E3%82%BF%E3%83%BC%E3%83%9F%E3%83%8A%E3%83%AB+%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80+%E3%83%89%E3%83%A9%E3%83%83%E3%82%B0&oq=mac+%E3%82%BF%E3%83%BC%E3%83%9F%E3%83%8A%E3%83%AB+%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80+%E3%83%89%E3%83%A9%E3%83%83%E3%82%B0&gs_l=psy-ab.3...430471.443777..444468...0.0..0.146.2845.27j4......0....1..gws-wiz.......35i39j0i4j0i131i4j0i131j0i131i67j0i67j0i131i4i10j0j33i21.mb-JKgWSOdc)へフォルダをドラッグすれば簡単に入力できます)

すると、ソースディレクトリ内にある png と jpeg を全て探し出して、書き出しディレクトリに「`6分の1画像@x1`」「`3分の1画像@x2`」「`2分の1画像@x3`」として書き出されます。
書き出しファイルは有無を言わせず上書きされますので注意してください。
また、ソース画像が PNG-8 のインデックス画像だった場合には、RGBA に変換されます。

## Photoshop との違い

Photoshop でも画像解像度を変えることができます(「イメージ」メニューの「画像解像度」)。この時、アルゴリズムの選び方によって出来上がりのイメージが変わってきます。
下は、6倍画像を$1/3$に解像度変換したものを拡大表示したものです。

![risizeAlgorithm.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181201/c99533b5-ed9f-527a-054c-d880eb04a205.png)

ニアレストネイバーは、単に画像を間引いて作られているのでギザギザが目立ちます。
バイキュービックは、画像の周辺に輪郭強調したような色が付いていますね。
写真ならともかく、アプリで使うボタン画像などはバイリニアが一番綺麗です。

RetinaFraction6 で使っているアルゴリズムは、画像の縦横がどちらも6の倍数なら面積平均法(Image.SCALE_AREA_AVERAGIN)、どちらかが6の倍数で無いときはバイリニア(だと思われる)(Image.SCALE_SMOOTH)を採用しています。
画像を整数分の1に変換する時は、面積平均法とバイリニアは同じ絵になります。それでもわざわざ面積平均法を使っているのは、変換スピードがバイリニアよりも速いためです。

つまり、RetinaFraction6 で変換した画像は、Photoshop でバイリニアを使った画像解像度の縮小と同じになります(たぶん)。
それでも、1つの画像から`@x1〜@x3`の3つの画像を作ってくれてファイル名まで適切に変えてくれるのは、まあまあ楽ちんです。

副作用として、RetinaFraction6 で作ったPNG画像は Photoshop でバッチ処理した画像よりもファイルサイズが小さくなるという違いがあります(Photoshop での保存はヘッダ部分に著作権情報とかを書いているみたいですね)。

## 6倍画像の作り方のコツ

RetinaFraction6 で処理する6倍画像ですが、Illustrator のプロファイルを「Web」で作ると綺麗です。
Xcodeでの論理ポイントサイズ(例えば iPhone6〜8 なら、375ドット×667ドット)に乗せる絵(つまり`@x1`サイズの絵)を Illustrator のWebプロファイルでポイントにスナップさせて作り、「Web用に書き出し」でサイズを600％に指定して書き出すと良いです。

四角形などは「線の外側に描画」で描くのがコツです。こうすると、$1/6$にしたときにアンチエイリアスの線が出ないのでエッジが綺麗になります。

その他のコツは、「Illustrator web ピクセル」とかで[ググって](https://www.google.com/search?ei=OLsJXbHGINKvyAPUx574BA&q=Illustrator+web+%E3%83%94%E3%82%AF%E3%82%BB%E3%83%AB&oq=Illustrator+web+%E3%83%94%E3%82%AF%E3%82%BB%E3%83%AB&gs_l=psy-ab.3..35i39j0i4.29896.30031..30968...0.0..0.93.176.2......0....1..gws-wiz.Y6-D8kZaQgo)調べてみてください。

Illustratorでは x1、x2、x3 の画像を出力できるのですが、やはりファイル名の変更を自分でやらないといけないのが面倒だったりします。

Photoshopで6倍画像を描きたいときは、グリッド間隔を6ピクセルとかにして作業すると良いと思います。
四角形の辺などはこの6ピクセルの外側にピッタリくっつくように描くと、RetinaFraction6 で処理した画像が綺麗に出来上がります。



## プログラムソースコード

RetinaFraction6 のソースコードも[晒して](https://drive.google.com/file/d/1j4KaOFeDA1hhAoFRZXHmgR7Q1bICAhLY/view?usp=sharing)おきます。
Javaを使ったのは、単に作者の慣れのためだけです。ごめんなさい。
簡単なプログラムなので、main の下にダラダラと書いちゃってます。

改変、再配布はご自由に。

## 所感

つまるところ、RetinaFraction6 を作った最大の理由は、ファイル名の一括変更が面倒だったってことですね。ファイル名の一括変更ぐらいは別の方法で出来ますが、ファイルを生成しつつファイル名も正しく変更してくれるってのは、考える事が1つ減って楽です。たくさんある画像の1つだけを描き直した時にも、ディレクトリ全部を更新しちゃえば良いやって感じで使えます。
ImageMagick を使ったスクリプトでも同じ事が出来ると思いますけど、元画像を1回しか読まないっていうのは早さに対するアドバンテージかもしれません(？)

私は結構、このツールが気に入っているんですけど、やっぱ6倍の画像を作るっていうのは変ですかね？