LoginSignup
104
106

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-02-04

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

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

CreateJS入門サイト - 自動生成ツールの紹介ビデオ

コードはリポジトリ「ics-creative/tutorial-createjs」にアップしているのですが、この部分に特化してQiitaで説明します。

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

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

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」の約80点の画像をキャプチャしています。めでたしめでたし。

104
106
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
104
106