Node.jsでフォルダ内の全HTMLをキャプチャし画像化

[![](http://clockmaker.jp/blog/wp-content/uploads/2016/02/160204_title.jpg)](http://clockmaker.jp/blog/2016/02/tutorial-createjs-github/)

記事「[Markdownから効率的なWebサイト制作を 〜 CreateJS入門サイト制作時に採用したGitを中心にした原稿執筆方法](http://clockmaker.jp/blog/2016/02/tutorial-createjs-github/)」では、Gitを活用した自動化・効率化のテクニックをガッツリと紹介しました。いろいろおもしろいテクニックがあるので、ぜひご覧下さい。


その記事の中で、さらっと紹介したフォルダ内の全HTMLをキャプチャし画像化する方法。:movie_camera:動画をみてもらうのが一番わかりやすく、:racehorse:最短で理解できると思うのですが、細かく説明してみたいと思います。

[![CreateJS入門サイト - 自動生成ツールの紹介ビデオ](http://img.youtube.com/vi/Djj3cFwMJbs/0.jpg)](http://www.youtube.com/watch?v=Djj3cFwMJbs)

コードはリポジトリ「[ics-creative/tutorial-createjs](https://github.com/ics-creative/tutorial-createjs/tree/gh-pages/tool-generate-captures)」にアップしているのですが、この部分に特化してQiitaで説明します。

## 最小構成のサンプルファイル

最小構成のサンプルのコードを、次のリポジトリに配置しています。Node.js v8以上でお試しください。

- [https://github.com/ics-creative/171004_phantomjs](https://github.com/ics-creative/171004_phantomjs)

## Node.js のモジュール

`package.json`にはモジュール`phantomjs`をインストールしておきます。最低限、次の記述だけで動作します。

```package.json
{
  "devDependencies": {
    "phantomjs": "^2.1.7"
  }
}
```

## 画像化するコード

画像化するには`phantomjs`を利用します。メインの実行ファイルと、画像生成プロセスの2つコードを用意するのがポイントです。


### main.js : メインの実行ファイル

非同期処理になるので、`Promise`とか使っています。

```main.js
// 定数宣言 (必要に応じて書き換えてください)
const TARGET_FOLDER = './samples'; // キャプチャーしたいHTMLのフォルダー
const OUTPUT_FOLDER = './imgs'; // 保存先のフォルダー
const VIEWPORT_W = '1024'; // viewportの横幅(幅：単位px)
const VIEWPORT_H = '768'; // viewportの高さ(幅：単位px)
const IGNORE_LIST = ['.DS_Store', 'Thumbs.db', '.idea']; // 無視リスト
const PHANTOM_JS_FILE = 'render.js'; // PhantomJSのパス

// 具体的な処理
const fs = require('fs');
const childProcess = require('child_process');
const phantomjs = require('phantomjs');
const binPath = phantomjs.path;

fs.readdir(TARGET_FOLDER, (err, files) => {
  const promises = [];
  files.map(file => {
    if (IGNORE_LIST.includes(file) === false) {
      const targetFilePath = `${TARGET_FOLDER}/${file}`;
      const outputFilePath = `${OUTPUT_FOLDER}/${file}.png`;
      const options = [
        PHANTOM_JS_FILE,
        targetFilePath,
        outputFilePath,
        VIEWPORT_W,
        VIEWPORT_H
      ];
      const childPromise = new Promise((resolve) => {
        // ここでrender.jsをphantomjsで呼び出して実行する
        childProcess.execFile(binPath, options, (error, stdout, stderr) => {
          // プロセスの対象を出力
          console.log(`${file} をPhantomJSで変換を試みました`);
          // PhantomJS側のconsole情報を出力
          console.log(stdout);
          if (error) {
            // 書き出し失敗の詳細情報を出力
            console.error(error);
          } else {
            // 書き出し成功
          }
          resolve();
        });
      });
      promises.push(childPromise);
    }
  });

  console.log(`${TARGET_FOLDER} フォルダーのキャプチャーを始めます。ちょっとまってね！`);

  Promise
    .all(promises)
    .then((results) => {
      console.log(`${TARGET_FOLDER} のキャプチャーが終わったので ${OUTPUT_FOLDER} に入れておきました!!`);
    });
});
```

### render.js : 画像生成プロセス

```render.js 
const page = require('webpage').create();
const system = require('system');

// 引数は、system.argsでアクセスできる。
const address = system.args[1];
const output = system.args[2];
const VIEWPORT_W = system.args[3];
const VIEWPORT_H = system.args[4];

page.viewportSize = {
  width: VIEWPORT_W,
  height: VIEWPORT_H,
};

page.open(address,
  function (status) {
    if (status === 'success') {
      // 出力
      page.render(output);
      console.error('キャプチャーに成功しました');
      // 成功として終了
      phantom.exit(0);
    } else {
      console.error('キャプチャーに失敗しました');
      // エラーとして終了
      phantom.exit(1);
    }
  }
);
```

## 実行方法

:black_large_square:黒い画面:black_large_square:を開いて次のコードを実行させます。実行して1分くらい待ったら自動的に画像ファイル:camera:ができあがります(YouTubeのビデオで示したとおり)。

```
node main.js
```

`main.js`というのはJavaScriptファイル`main.js`の名前です。


## まとめ

こんな感じにして「[CreateJS入門サイト - ICS MEDIA](https://ics.media/tutorial-createjs/index.html)」の約80点の画像をキャプチャしています。めでたしめでたし。

![](http://clockmaker.jp/blog/wp-content/uploads/2016/02/160204_captures.png)