【Express】GitHubでよく見るあのアイコンを実装する

# あのアイコンって？
![github-identicon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/13dd16b3-b9a3-187d-1c02-e5c00ee6585a.png)
- GitHubの初期アイコンの事です。
    - identiconと呼びます。 
# 準備
### express-generatorを使って雛形を作成する
express-generatorがインストールされていない場合は

    npm install -g express-generator
    express --views=ejs identicon-express
    cd identicon-express
    npm install
    
express-generatorがインストールされている場合は

    express --views=ejs identicon-express
    cd identicon-express
    npm install

# ディレクトリ構造を確認する
    identicon-express/
    ├── bin
    ├── node_modules
    ├── public
    │   ├── images
    │   ├── javascripts
    │   ├── stylesheets
    ├── routes
    │   ├── index.js
    │   ├── users.js
    ├── views
        ├── error.ejs
        ├── index.ejs
    ├── app.js
    ├── package-lock.json
    ├── package.json
    
# ライブラリをインストールする
    npm install identicon.js
    
# 適当なアイコンを画面に描画させてみる
- routes/index.js
```
const Identicon = require("identicon.js");
var express = require('express');
var router = express.Router();
    
/* GET home page. */
router.get('/', function(req, res, next) {
    const data = new Identicon("fdspmfdspm432094329042fasfhodsa0", 64).toString();
    res.render('index', { data });
});

module.exports = router;
```
- views/index.ejs
```
<!DOCTYPE html>
<html>
  <head>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <img src="data:image/png;base64, <%= data %>">
  </body>
</html>
```
- ### localhost:3000にアクセスする
![identicon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/92ab6b7a-41af-4afe-ee15-8088d2e4e8f1.png)
このようなアイコンが表示されることが確認出来ます
# 描画を行ったコードを確認する
- ##### routes/index.js
```
const Identicon = require("identicon.js");

const data = new Identicon("fdspmfdspm432094329042fasfhodsa0", 64).toString();
res.render('index', { data });
```
- identicon.jsを読み込んでインスタンスを生成しています。
第1引数には16進数で15文字以上の文字列を渡します。
第2引数には画像の大きさを渡します。
第1引数に渡した文字列によって生成される画像が変わります。
toString()で取得した文字列はbase64エンコードを施された文字列になっています。
- ##### views/index.ejs
```
<img src="data:image/png;base64, <%= data %>">
```
- base64エンコードを施された画像データを含む文字列を画像データとして描画しています。
# 任意の文字列に対してアイコンを生成する
- ##### routes/users.js
```
const Identicon = require("identicon.js");
const crypto = require("crypto");

var express = require('express');
var router = express.Router();

router.get('/:username', function(req, res, next) {
  const { username } = req.params;
  const hashStr = crypto.createHash("md5").update(username).digest("hex");
  const data = new Identicon(hashStr, 64).toString();
  res.render("index", { data });
});

module.exports = router;
```
- /users/hogeにアクセスされるとhogeを取得して変数に代入しています。
任意の文字列に対応しているので/users/fugaにアクセスするとfugaが取得されて変数に代入されます。
代入した文字列からハッシュ化した16進数の文字列を生成します。
ハッシュ化された文字列を使ってアイコンを生成します。

- ##### views/index.ejs
```
<!DOCTYPE html>
<html>
  <head>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <img src="data:image/png;base64, <%= data %>">
  </body>
</html>
```
- 生成されたアイコンはbase64エンコードが施された画像データを含む文字列なので、その旨を指定してimgタグで描画します。

# 最後に
- base64エンコードが施された画像データを含む文字列というのは結局文字列なのでテンプレートエンジンだけでなくReactやNext.jsのようなモダンなフロントエンド環境でも使用することが出来ます。
- Browserifyを使ってJSファイルに出力することでDOMとしても使用出来ます。