ボタンクリック時にhtml2canvasで保存した画像をダウンロードさせる方法
仕事でjavascriptを利用して、表とかグラフを作っています。簡単にグラフを保存させたいと要望があったので、html2canvasとblobを使ってダウンロードさせる処理を作成しました。
必要なファイル
- html2canvas http://html2canvas.hertzen.com/
指定した要素の中身をcanvasへ変換してくれる - polyfill.min.js https://cdn.polyfill.io/v2/polyfill.min.js
これがないとIEでhtml2canvasが動かない
サンプルサイト
http://hinanaoblog.xyz/hinanao/html/html2canvas/test.html
簡単な処理内容
- 画像保存ボタンをクリックしたときに処理開始する。
- divタグのidがtarget内の表示内容をcanvasへ変換する。
- canvasをbase64へ変換する。
- IEの時blob形式へ変換し、ダウンロード処理を開始する。
それ以外(検証したのはFireFoxとchrome)base64をhrefへ設定し、リンクを自動的にクリックさせる。
ソースコード
- 以下のソースコードを動作させるには、同じフォルダ内にダウンロードしたhtml2canvas.min.jsとサンプル用画像をtest.pngという名前で保存してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | <!DOCTYPE html> <html lang="ja"> <head> <title>html2canvasテスト</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script> <script src="html2canvas.min.js"></script> <script type="text/javascript"> function getDisplayImage(){ //html2canvas実行 html2canvas(document.getElementById("target")).then(function(canvas) { downloadImage(canvas.toDataURL()); }); } function downloadImage (data) { var fname ="testimage.png"; var encdata= atob(data.replace(/^.*,/, '')); var outdata = new Uint8Array(encdata.length); for (var i = 0; i < encdata.length; i++) { outdata[i] = encdata.charCodeAt(i); } var blob = new Blob([outdata], ["image/png"]); if (window.navigator.msSaveBlob) { //IE用 window.navigator.msSaveOrOpenBlob(blob, fname); } else { //それ以外? document.getElementById("getImage").href=data; //base64そのまま設定 document.getElementById("getImage").download=fname; //ダウンロードファイル名設定 document.getElementById("getImage").click(); //自動クリック } } </script> </head> <body> <div> <input id="downloadImageButton" style="width:120px;" type="button" value="画像保存" onclick="getDisplayImage();" > <a id="getImage" href="" style="display:none;" download="image.png">画像保存</a> </div> <hr> <div id="target" style="width:500px;height:500px"> <img id="work" src="test.png"/> <div style="position:absolute;z-index:10;font-size:28px;top:150px;left:250px;background-color:#FFFFFF;">仕事中</div> </div> </body> </html> |
動作確認環境
Internet Explorer 11.0.60(64ビット)
FireFox 60.0.2(64ビット)
Google Chrome 67.0.3396.87(64ビット)
履歴
- 2018/12/23 ソースコードを動作させる条件を追記しました。ソースコード内のdivタグが1つ余分に記述しておりました。コメントでのご指摘ありがとうございました。
divの数がおかしいです。
このまま実行したら「Uncaught (in promise) ReferenceError: downloadImage is not defined」と出ます。