jquery.qrcode.js を使用して生成したQRコードをPNG画像として保存する
jquery.qrcode.jsとは
jquery.qrcode.js
http://jeromeetienne.github.io/jquery-qrcode/
- QRコードを生成するjQueryプラグイン
- 画像は生成されず、tableタグまたはcanvasタグで描画することができる。
- ソースはGitHubで公開されている。
使用手順
- GitHubから jquery.qrcode.min.js をダウンロードし、jQuery本体よりあとで読み込む
- HTML側に描画スペースを用意
- 用意した要素に対してjQueryスクリプトを記述
使用例
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>1903-qrcode</title>
</head>
<body>
<!-- 描画スペースの用意 -->
<div id="hoge"></div>
<!-- js読み込み -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="jquery.qrcode.min.js"></script>
<!-- スクリプトを記述 -->
<script>
$(function(){
$('#hoge').qrcode('ここにQRコード化したい文字列をいれる');
});
</script>
</body>
</html>
- 現在表示しているページのURLを取得してQRコード化する場合は、引数に location.href を指定する。
$(function(){
//現在表示しているページのURLをQRコード化する
$('#hoge').qrcode(location.href);
});
- オプションでQRコードの横幅、縦幅、レンダリング方法(tableまたはcanvas)を指定できる。
- サンプル:https://hi3103.net/study/1903-qrcode/sample-1.html
- 何も指定しないと 256*256 の canvas で出力される。
$(function(){
//現在表示しているページのURLをQRコード化する
$('#hoge').qrcode({
text: location.href,
width: 600, //横幅
height: 600, //縦幅
render: 'canvas', //tableまたはcanvas
});
});
参考URL
ブラウザの機能でPNG画像として保存する
FirefoxおよびChromeでは単純に「右クリックで保存」すると、PNG画像として保存することができた。
- 動作環境
- Mac OS Mojave 10.14.4
- ブラウザ・バージョン
- Mozilla Firefox 66.0.2
- Google Chrome 73.0.3683.86
なお、Safari 12.1 でも試したがこちらは動作せず。
また、iOSではどのブラウザでも画像としての保存はできなかった(iOS 12.1.4 のSafari、Chrome 73.0.3683.68、Firefox 15.1で確認)。
canvas の toDataURL()メソッドでPNG画像を出力する
【失敗例】QRコードをクリックするとPNG画像が別窓で開くようにする
【2019-04-15追記】このソース、Firefoxでは動くけど、Chromeだと動かないことに気づきました。**
$(function(){
//現在表示しているページのURLをQRコード化する
$('#hoge').qrcode(location.href);
//生成されたQRコード(=canvas要素)を変数にセット
var canvas = $('#hoge canvas');
//クリックできることを明示するためcssでカーソル種類を指定
canvas.css('cursor','pointer');
//QRコードがクリックされたらPNG画像が新しい窓で開く
canvas.click(function() {
var data = canvas[0].toDataURL('image/png');
window.open(data);
});
});
もしもJPEG画像として出力したい場合は toDataURL の引数を image/jpeg に変更する。
var data = canvas[0].toDataURL('image/jpeg');
参考URL
- HTML5 の canvas 要素を base64 文字列化し画像として保存する方法まとめ – Qiita
- javascript – toDataURL not a function – Stack Overflow
【成功例】ボタンクリックでPNG画像をダウンロードできるようにする(2019-04-15追記)
- Chromeはブラウザの仕様で data:image/png;base64, …をそのまま開くことができない。
- 上述の window.open() のほか、location.href で直接指定してもダメだった。
- 以下のエントリーのソースを頂戴して「ボタンクリックでPNG画像をダウンロード」するようにした。
- サンプル:https://hi3103.net/study/1903-qrcode/sample-3.html
$(function(){
//現在表示しているページのURLを取得し、QRコードを生成
$('#hoge').qrcode(location.href);
//生成されたQRコード(=canvas要素)にIDを付与し、非表示にする
$('#hoge canvas').attr('id','piyo').css('display','none');
//ダウンロードボタンを生成
$('#hoge').append('<button onclick="saveCanvas();">QRコードをダウンロードする</button>');
});
//--- ここから下は https://oar.st40.xyz/article/133 の内容を頂戴しました ----//
// canvas上のイメージを保存
function saveCanvas(){
//ファイルタイプとファイル名を指定
var imageType = 'image/png';
var fileName = 'qrcode.png';
//特定のIDが付与された要素を変数にセット
var canvas = document.getElementById('piyo');
// base64エンコードされたデータを取得 「data:image/png;base64,iVBORw0k~」
var base64 = canvas.toDataURL(imageType);
// base64データをblobに変換
var blob = Base64toBlob(base64);
// blobデータをa要素を使ってダウンロード
saveBlob(blob, fileName);
}
// Base64データをBlobデータに変換
function Base64toBlob(base64){
// カンマで分割して以下のようにデータを分ける
// tmp[0] : データ形式(data:image/png;base64)
// tmp[1] : base64データ(iVBORw0k~)
var tmp = base64.split(',');
// base64データの文字列をデコード
var data = atob(tmp[1]);
// tmp[0]の文字列(data:image/png;base64)からコンテンツタイプ(image/png)部分を取得
var mime = tmp[0].split(':')[1].split(';')[0];
// 1文字ごとにUTF-16コードを表す 0から65535 の整数を取得
var buf = new Uint8Array(data.length);
for (var i = 0; i < data.length; i++) {
buf[i] = data.charCodeAt(i);
}
// blobデータを作成
var blob = new Blob([buf], { type: mime });
return blob;
}
// 画像のダウンロード
function saveBlob(blob, fileName){
var url = (window.URL || window.webkitURL);
// ダウンロード用のURL作成
var dataUrl = url.createObjectURL(blob);
// イベント作成
var event = document.createEvent("MouseEvents");
event.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
// a要素を作成
var a = document.createElementNS("http://www.w3.org/1999/xhtml", "a");
// ダウンロード用のURLセット
a.href = dataUrl;
// ファイル名セット
a.download = fileName;
// イベントの発火
a.dispatchEvent(event);
}
【備考1】URLの余計なパラメータを除去する
- 現在表示しているページに余計なパラメータがついていて、それを除去したい場合は、冒頭部分を以下のように書き換えればOK。
//現在表示しているページのURLを取得し、余計なパラメータを取る
var url = location.href;
url = url.replace(/\?.+$/,'');
//QRコードを生成
$('#hoge').qrcode(url);
【備考2】ダウンロードボタンだけを表示する
- 大きめのQRコードを生成したいが、デカイと邪魔なのでQRコードは非表示にしておきたいという場合は、canvas属性にID付与する際にCSSで display:none を設定すればOK。
//生成されたQRコード(=canvas要素)にIDを付与し、非表示にする
$('#hoge canvas').attr('id','piyo').css('display','none');
生成したQRコードをSVG画像として保存できないか?
結論:できなかった。
試したものは以下。
- fabric.jsの toSVG()メソッド
- CreateJSのEaselJSに同梱されている試験的な機能:SVGExporter
いずれもcanvasの機能拡張的なライブラリで、canvasをSVGに変換・書き出しする機能は備わっているが、
- 描画領域をセット
- 描画する
- 描画したものを書き出す
という工程になっているため、「すでにjquery.qrcode.jsによって描写されたcanvasをSVGに書き出す」ことができなかった。
以下、動かなかったソースのメモ。
// ※失敗作※ canvasのガワだけの状態 (canvasのwidth・heightの情報だけは持っている白紙のSVG) が出力される
$(function(){
//現在表示しているページのURLをQRコード化する
$('#hoge').qrcode(location.href);
//生成されたQRコード(=canvas要素)をidを付与
$('#hoge canvas').attr('id','piyo');
//描画領域をセット
var stage = new createjs.Stage('piyo');
//QRコードがクリックされたらsvgデータが出力される
$('#hoge').click(function() {
exporter = new SVGExporter(stage, false, false, false);
exporter.run();
document.body.appendChild(exporter.svg);
});
});