LoginSignup
3
5

More than 3 years have passed since last update.

Node.js + Puppeteer を使って無料でデスクトップより大きなスクリーンショットを撮る 4k 8k

Posted at

はじめに

建築系のCG制作プロダクションで3DCGモデラーをしています。

建築の仕事をしていると、広範囲・高解像度の地図とか航空写真が欲しい時があります。
一番簡単なのは、国土地理院の地理院地図から画像を保存することです。
無料ですし、簡単で大変便利です。ただ、この地図、若干、古いんです

もっと新しい地図が欲しければ、ゼンリンやMapFanみたいな地図会社の有料サービスを利用するか、
GoogleマップやYahooマップでスクリーンショットを撮るしかありません。

高解像度のスクリーンショット

"無料で"というと、スクリーンショットを撮ることになります。

ただ、"広範囲・高解像度" となると、デスクトップよりずっと大きな画像になります。
普通にスクリーンショットを撮ろうとすると1画面に収まりません。デュアルディスプレイでも無理です。

ブラウザのエクステンションに、"ページ全体のスクリーンショットを撮る"ものがありますが、
画像のキャッシュなどの問題で、キレイに撮るのはなかなか大変です。

なので以前は、仕方なくスクリーンショットをたくさん撮って、Photoshopで合成してました...。

Chromeを自動操作出来るpuppeteer

puppeteernode.js上で動くChromeを自動操作するためのライブラリです。
大変短いコードで簡単にWEBページのスクリーンショットを撮れます。
Puppeteer API

本来、WEBテスト用のツールですが、"ウィンドウサイズを指定"出来るので、
4kでも8kでも任意のサイズのスクリーンショットを撮れます。

インストール

node.js Install
puppeteer Install

実践

以下、Yahooマップの写真モードでやってみました。

main.js

// yahoo maps in Japan
const url = 'https://yahoo.jp/scdMa0'; //マップの表示設定をした後、URLを取得(アドレスバーのじゃなくて、アイコンの"URLボタン"のほうから取る)

(async() => {
    const puppeteer = require('puppeteer');
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.setDefaultNavigationTimeout(120000);
    const response = await page.goto(url,{waitUntil:"networkidle2"});
    let n = 4;
    let k = 1024;
    // 4k = 4096 pixel x 4096 pixel 
      try {
            let map_area = '#map';
            await page.setViewport({width:n*k,height:n*k}); // ウィンドウサイズを指定
            for (let i = 2; i > 0; i--) { // ブラウザにキャッシュさせるために2回繰り返す
                await page.waitFor(90000); //通信環境にもよると思いますが、少し待たないと画像が全部来ないです。
                if(i == 1){
                    let img_name = 'map_'+ n +'k' + i + '.jpg';
                    const map_area_Handle = await page.$(map_area);
                    await map_area_Handle.screenshot({path: img_name});
                    console.log(img_name);
                }
        }

      } catch (e) {
        console.log(e);

        throw e;
      } finally{
          await browser.close();
      }
})();



run.bat
node main.js

結果

最大ズームで8k画像(8192 pixel x 8192 pixel)を取得出来ました。
sct20190527090741.png

画像サイズについて

ウチの通信環境だと、8kはうまくいかない時があります。
画像タイルが全部ロードされず、歯抜けになってしまうことがあります。

12kでも試してみましたが、全然撮れません...。半分しか画像が来ません。
4kくらいまでならちゃんと撮れます。

扱いやすいサイズにする

そもそも、あまり画像サイズがデカいと後で扱いにくいので、
最終的に、大きくても4kに収まるようにするのがよいと思います。
理想的には2k以下が軽くていいです。大抵は事足ります。

広さが足りなければ、ズームアウトすればいいですし、
一部分だけでも高解像度が欲しければ、そのエリアと周囲を分けるといいと思います。

動くことは動くけど

シンプルなコードですが、ちゃんと絵が撮れるようになるまでちょっと苦労しました。
画像が全部ロードされるまで待つ方法が分からず、結局、時間指定です。

node.jsって何?ってところから始めたので、エンジニアでもなんでもない自分にとっては上出来ですが...。
うまい方法わかる方いらっしゃいましたら、ご教授ください。

3
5
0

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
3
5