HashLipsのビルド結果をマージする機能を作った 

ジェネラティブNFTでは、複数のパーツをランダムに合成して画像を生成します。
ランダムに合成する面白さがある反面、イマイチな組み合わせも出てきてしまうので、選別しつつ繰り返し合成作業を行います。
[HashLips](https://github.com/HashLips/hashlips_art_engine)では、ランダムに合成することはできますが、その都度全部作り直しになるため、選別結果との重複などの問題が出てきます。
このため、[HashLips](https://github.com/HashLips/hashlips_art_engine)のビルド結果をマージする機能を作りました。

## インストール

機能追加したリポジトリのブランチは以下になるので、インストールします。
https://github.com/two-pack/hashlips_art_engine/tree/features

```bash
$ git clone -b features https://github.com/two-pack/hashlips_art_engine.git
$ cd hashlips_art_engine
$ npm install
```

## 使い方

以下のようなコマンドを実行します。

```bash
npm run merge -- -o build build_a build_b build_c -s
```

-oオプションは出力先フォルダの指定（上ではbuild）、それ以降のマージ元となるフォルダ名（上ではbuild_a～build_c）を指定します。
-sオプションを指定すると、マージ後に順番をシャッフルします。

## 使用例

この記事でも使った[棒人間ブランチ](https://github.com/two-pack/hashlips_art_engine/tree/example_stick_figure)を使って、使用例を説明します。ブランチには今回の修正を追加済みです。
最終的には50個の画像が欲しい、ということで進めます。

まず、普通にビルドします。
```bash
$ npm run build

> hashlips_art_engine@1.1.1 build /home/foo/bar
> node index.js

Created edition: 1, with DNA: 12107f9ddeaa56e9738b73b5e1cbdf41efb72257
Created edition: 2, with DNA: b9fe6ffefbf85a81823278258c75e901fb28d1f0
Created edition: 3, with DNA: e7dfca565bd4b6a40bc0d30f4498ecf3fb345f50
Created edition: 4, with DNA: b11f11bea4ab2cfa4dcd2e2865b944a0f7add35a
<snip>
Created edition: 48, with DNA: 80c3dedec33b86dcdfddde6a0bdc237b56b4263d
DNA exists!
Created edition: 49, with DNA: 00c04a53023b1636050faad38af943add6a2338b
Created edition: 50, with DNA: 73291eaeb155324048d706e9ebd05ec009508df0
```

50個の結果ができます。
![preview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30716/671cac9d-dd1e-8631-1d36-014805663d9b.png)
ここで選別作業を行います。imagesフォルダ内の画像ファイルと、jsonフォルダ内のメタデータの両方を消していきます。
今回は **1.png～20.pngまでの20個を削除** しました。
削除後にフォルダをリネームします。今回は、 **build → build_a** と変更します。

次に再度ビルドします。そうするとまた50個できます。ランダムに生成されるので先程とは違う結果になりました。
![preview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30716/47811c73-ffa5-cafc-7efa-397fd9eaa2ac.png)

先程と同様にこちらも選別します。今回も20個消します。
削除後にフォルダをリネームします。今回は、 **build → build_b** と変更します。

これで2つのビルド結果 **build_a、build_b** ができたのでマージします。

```bash
$ npm run merge -- -o build build_a build_b

> hashlips_art_engine@1.1.1 merge /home/foo/bar
> node utils/merge.js "-o" "build" "build_a" "build_b"

Duplicated data:  /home/foo/bar/build_b/json/25.json
Duplicated data:  /home/foo/bar/build_b/json/29.json
Duplicated data:  /home/foo/bar/build_b/json/34.json
Duplicated data:  /home/foo/bar/build_b/json/46.json
Duplicated data:  /home/foo/bar/build_b/json/49.json
Merge done.
```

**Duplicated data** で表示された5つの画像が、1回目と2回目で重複していたものです。
このため、それを除いたものが結果となるため、
　**build_aの30個 + build_bの30個 - 重複5個 = 55個**
がbuildフォルダに入っています。
![preview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30716/abd85a70-40be-9c6b-8344-c560f5d6bace.png)

目標の50個よりも多いので更に5個選別します。 **1.png～5.pngを削除** することにします。
削除したら **build → build_o** とフォルダをリネームします。
今回は複数のフォルダではないですが、 **同じ機能を使って番号を振り直しを行います。** また、ついでに **-sオプションを付けて順番もシャッフル** します。

```bash
$ npm run merge -- -o build build_o -s

> hashlips_art_engine@1.1.1 merge /home/foo/bar
> node utils/merge.js "-o" "build" "build_o" "-s"

Merge done.
```

結果は以下のように50個になりました。メタデータや画像を確認するとわかりますが、1～50に番号が振り直されています。
![preview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30716/12877c83-6c2b-ba74-038b-2a864476038a.png)

## プルリクエスト

本家へのプルリクエストは以下です。
https://github.com/HashLips/hashlips_art_engine/pull/1561

## 最後に

こんな感じで何度も試したビルドの結果から、決めた数に選別していくことができそうです。
よかった😁