女の子の好みの男のタイプをnodejsを使って勝手に決める

##はじめに
[前回の記事](https://qiita.com/Riti0208/items/c1b041bb3cd5139a9407)では自作デバイスを使ったゲームを作った話をしました。
その中の女の子のパラメータを決める際に画像の色情報からnodejsを用いてパラメータを生成しました。
使用しているライブラリの使用例を書いている人がいなかったのでメモついでに書きます。

##1.仕様ライブラリ
[get-image-colors](https://www.npmjs.com/package/get-image-colors)
指定した画像に含まれている色を上位5色を出力してくれるライブラリ
[color-classifier](https://blog.wadackel.me/2016/color-classifier-js/)
色を分類してくれるライブラリ

##2.準備
前回の記事と同様[ゆるドラシル](http://yurudora.com/tkool/)の画像を使わさせていただきます。
はーたん可愛いです。
<img width="320" alt="115601.png" src="https://qiita-image-store.s3.amazonaws.com/0/190143/f774d337-37a9-8096-11c7-1df74d86f828.png">

まず今回使うライブラリをインストールします

```
npm i --save get-image-colors
npm i --save color-classifier
```

##3.実装-色の抽出-

色を抽出するコードがこちらです。

```javascript:javascript
const path = require('path')
const getImageColors = require('get-image-colors')

getImageColors(path.join(__dirname, './female/115601.png')).then(colors => {
  for(let i=0;i < colors.length;i++){
    console.log(change16bitColorToObj(colors[i]))
  }
})

function change16bitColorToObj(color){
  let bitR = color._rgb[0].toString(16)
  if(bitR.length === 1) bitR = '0' + bitR
  let bitG = color._rgb[1].toString(16)
  if(bitG.length === 1) bitG = '0' + bitG
  let bitB = color._rgb[2].toString(16)
  if(bitB.length === 1) bitB = '0' + bitB
  return '#' + bitR + bitG + bitB
}

```

実行すると

`#ccb4b0`
`#242129`
`#463b4b`
`#5f5b63`
`#785c3e`

このように色が多い順で出力されます。
##4.実装-色の分類-

指定の色に分類する場合のコードがこちらです。

```javascript:javascript
const path = require('path')
const getImageColors = require('get-image-colors')
const colorClassifier = require('color-classifier')

const palette = [ '#ff0000', '#ffffff', '#000000','#0000ff', '#ff6666', '#00ff00', '#ffff00']

const ccf = new colorClassifier(palette)

getImageColors(path.join(__dirname, './female/115601.png')).then(colors => {
  for(let i=0;i < colors.length;i++){
    let color = ccf.classify(change16bitColorToObj(colors[i]))
    console.log(change16bitColorToSting(color))
  }
})

function change16bitColorToObj(color){
  let bitR = color._rgb[0].toString(16)
  if(bitR.length === 1) bitR = '0' + bitR
  let bitG = color._rgb[1].toString(16)
  if(bitG.length === 1) bitG = '0' + bitG
  let bitB = color._rgb[2].toString(16)
  if(bitB.length === 1) bitB = '0' + bitB
  return '#' + bitR + bitG + bitB
}
function change16bitColorToSting(color){
  let bitR = color.r.toString(16)
  if(bitR.length === 1) bitR = '0' + bitR
  let bitG = color.g.toString(16)
  if(bitG.length === 1) bitG = '0' + bitG
  let bitB = color.b.toString(16)
  if(bitB.length === 1) bitB = '0' + bitB
  return '#' + bitR + bitG + bitB
}

```

先ほどの色を
```const palette = [ '#ff0000', '#ffffff', '#000000','#0000ff', '#ff6666', '#00ff00', '#ffff00']```
の色に分類して出力します。

`#ffffff`
`#000000`
`#000000`
`#000000`
`#ff0000`
##5.実装-性格の分類-

最後に分類してから性格に割り当てるコードがこちらです。

```javascript:javascript
const path = require('path')
const getImageColors = require('get-image-colors')
const colorClassifier = require('color-classifier')

const maleType = ['熱血', '純粋', '厨二', '冷静', '個性的', '草食系', '活発']

const palette = [ '#ff0000', '#ffffff', '#000000','#0000ff', '#ff6666', '#00ff00', '#ffff00']

const ccf = new colorClassifier(palette)

getImageColors(path.join(__dirname, './female/115601.png')).then(colors => {
  for(let i=0;i < colors.length;i++){
    let color = ccf.classify(change16bitColorToObj(colors[i]))
    console.log(maleType[palette.indexOf(change16bitColorToSting(color))])
  }
})

function change16bitColorToObj(color){
  let bitR = color._rgb[0].toString(16)
  if(bitR.length === 1) bitR = '0' + bitR
  let bitG = color._rgb[1].toString(16)
  if(bitG.length === 1) bitG = '0' + bitG
  let bitB = color._rgb[2].toString(16)
  if(bitB.length === 1) bitB = '0' + bitB
  return '#' + bitR + bitG + bitB
}
function change16bitColorToSting(color){
  let bitR = color.r.toString(16)
  if(bitR.length === 1) bitR = '0' + bitR
  let bitG = color.g.toString(16)
  if(bitG.length === 1) bitG = '0' + bitG
  let bitB = color.b.toString(16)
  if(bitB.length === 1) bitB = '0' + bitB
  return '#' + bitR + bitG + bitB
}

```

```const maleType = ['熱血', '純粋', '厨二', '冷静', '個性的', '草食系', '活発']```

この配列から割り振っていて
出力するとこのように表示されます。

```
純粋
厨二
厨二
厨二
熱血
```
ゲーム内では上位３色の性格をパラメータに入れています。
##終わりに
最近nodejsがサーバーだけではなくクライアントサイドなどでもよく使われています。
できることが多すぎるのと容易にできるようなライブラリも多いので
クライアントサイドしか作らない人とかも試しに触れたらいいと思います。