Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
174
Help us understand the problem. What is going on with this article?
@youwht

[JavaScript] JSだけでスクリーンショットを撮ってダウンロードもする方法

More than 1 year has passed since last update.

背景

htmlファイルを画像化して送って欲しい、共有したい、という時はどうしますか?
htmlの画像化は実はいろいろな使い道があります。

  • サムネイルを表示したい
  • 問い合わせの際に、そのページの状態を把握したい
  • 動的に変更されるサイトの断面図を保存したい   ...などなど

もちろん、htmlファイルを画像化する方法は様々あります。
SnippingTool、WinShot、PRTSCキー、各ブラウザのプラグイン、各種ツール・・・。
しかし、どれもクライアント側に何か準備が生じ、意外と面倒で環境にも左右されます。
htmlを見る送り手側にとって結構手間になりますので、html提供側にその機能を組み込みたいですよね。

本投稿の内容

JavaScriptだけで、htmlのスクリーンショットを撮れる「html2canvas」の紹介をします。
最後の実コードを使ってすぐにお手元で試すことが出来ます。

  • JavaScriptだけで実現(クライアント側にソフトは不要)
  • スクリーンショットを撮って画像として表示する
  • 撮ったスクリーンショットをダウンロード出来るようにする
  • 出来たファイルをPDF化したり、直接サーバにPOSTしたり、もこの応用で可能です。
  • (本投稿では応用編までは踏み込みません)

※html2canvasを解説しているサイトはいくつかあったのですが、どれも分かりにくかったり、
 説明不足な印象なため、使いやすいコード例としてまとめるために作りました。

html内でスクリーンショットを撮った例

百聞は一見に如かず、実際に作成したHTMLのキャプチャ画像

  • 一見、同じ表が二個ありますが、上はhtml、下はそれを画像化して表示したものです。
  • さらにこの画像自体、「スクリーンショットをダウンロード」のボタンで生成したものです。

html_ss.png

実現方法

html2canvas.js というライブラリですぐに実現可能です。

html2canvasの使い方

//ロードされた際の処理として実施:
window.onload = function(){
  //HTML内に画像を表示
  html2canvas(document.getElementById("target"),{
    onrendered: function(canvas){
      //imgタグのsrcの中に、html2canvasがレンダリングした画像を指定する。
      var imgData = canvas.toDataURL();
      document.getElementById("result").src = imgData;
    }
  });
}

注意点として、このライブラリは、本当にスクリーンショットを撮っているのではありません。
DOMやCSSを解釈して、Canvas上に描画するという、いわばjsで出来たレンダリングエンジンなのです。
そのため、ブラウザと表示が異なったり、flashやiframeは上手くキャプチャ出来なかったりします。

■ コードの全文 ■

  • 丸ごと張り付けてhtmlファイルを作れば、このファイル単体で直ぐにお手元で試すことが出来ます。
HTML_Capture.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>JavaScriptで撮るスクリーンショット</title>
</head>
<body>

  <hr>
  <div style="background-color : #AAEEDD"><h1>JavaScriptで撮るスクリーンショット</h1></div>
  <div id="target">
  <h2>導入方法と処理概要</h2>
  <table border="1" width="500" cellspacing="0" cellpadding="5" bordercolor="#333333" style="table-layout: fixed;">
    <tr>
      <th bgcolor="#7b9ad0" width="40"><font color="#FFFFFF">No</font></th>
      <th bgcolor="#7b9ad0" width="230"><font color="#FFFFFF">概要</font></th>
      <th bgcolor="#7b9ad0" width="230"><font color="#FFFFFF">補足</font></th>
    </tr>
    <tr>
      <td bgcolor="#b1d7e4" width="40" align="right"></td>
      <td bgcolor="#FFFFFF" width="230" >html2canvas.jsを読み込む</td>
      <td bgcolor="#FFFFFF" width="230" ></td>
    </tr>
    <tr>
      <td bgcolor="#b1d7e4" width="40" align="right"></td>
      <td bgcolor="#FFFFFF" width="230" >任意のタイミングでhtml2canvas関数を呼ぶ</td>
      <td bgcolor="#FFFFFF" width="230" >※今回はオンロード処理</td>
    </tr>
    <tr>
      <td bgcolor="#b1d7e4" width="40" align="right"></td>
      <td bgcolor="#FFFFFF" width="230" >onrendered 処理にて指定のElementに画像を追記</td>
      <td bgcolor="#FFFFFF" width="230" >※[img]タグの[src]や、[a]タグの[href]など</td>
    </tr>
  </table>
  </div>
  <br>
  <hr>
  <h3>↓↓ここから画像↓↓ (上の対象のDIVを画像化)<h3>
  <img src="" id="result" />
  <h3>↑↑ここまで画像↑↑</h3>

  <hr>

  <a href="" id="ss" download="html_ss.png">スクリーンショット(document.body全体)をダウンロード</a>

  <hr>
  <h3>注意</h3>
  <ul>
    <li>実際にはスクリーンショットを撮っているわけではない</li>
    <li>html2canvasは、HTML内のDOMやCSSを解釈してCanvas上に描画するライブラリ</li>
    <li>つまり、レンダリングエンジンに近い動作をする</li>
    <li>そのため、ブラウザと異なる表示がされる場合がある</li>
    <li>flashやapplet,iframe(別URL)はうまくキャプチャできない</li>
  </ul>
  </div>


  <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.js"></script>
  <script>
    //ロードされた際の処理として実施:
    window.onload = function(){

      //HTML内に画像を表示
      html2canvas(document.getElementById("target"),{
        onrendered: function(canvas){
          //imgタグのsrcの中に、html2canvasがレンダリングした画像を指定する。
          var imgData = canvas.toDataURL();
          document.getElementById("result").src = imgData;
        }
      });

      //ボタンを押下した際にダウンロードする画像を作る
      html2canvas(document.body,{
        onrendered: function(canvas){
          //aタグのhrefにキャプチャ画像のURLを設定
          var imgData = canvas.toDataURL();
          document.getElementById("ss").href = imgData;
        }
      });

    }
  </script>

</body>
</html>

以上

174
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
youwht
「Qiitaの殿堂」(http://youwht.ml/) 「赤の他人の対義語」 「平成の次の元号」 「写経を自動化」 「パワポリント君」etc... wwwxuexihanyu@gmail.com
nri
NRIは「コンサルティング」「金融 ITソリューション」「産業 ITソリューション」「IT 基盤サービス」の4事業でお客様のビジネスや快適な社会、暮らしを支えています。※各記事の内容は個人の見解であり、所属する組織の公式見解ではありません。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
174
Help us understand the problem. What is going on with this article?