MonacaでQRコードリーダを作ってみた – JS編

こんにちは、浦本です。

昨日と今日で行われた ad:tech tokyo 2012 では、アシアルブースにてMonacaをアピールしてきました。
ブースにお立ち寄り頂いた方々、誠にありがとうございました!
イベントの模様は別途記事でご紹介できればと思います。

さて、今回はMonacaでQRコードリーダアプリを作ってみようと思います。
とはいってもQRコードを読み取るJSライブラリを利用するので簡単です。
今回作成するアプリは、まずPhoneGapを利用してカメラまたはアルバムから画像を取得し、その画像をJSライブラリに読み込ませてQRコードを解析するというものです。


JSなのでさほど速度は出ませんが、あくまでサンプルとして見て頂ければと思います。
※MonacaではQRコード解析用のPhoneGapプラグインに対応予定ですので、今回の記事タイトルではあえて「JS編」と記載させて頂きました。

アプリ作成手順は以下の通りです。Monacaは無料で利用できますので、ぜひ登録して試してくださいね。

【新規プロジェクトの作成】
Monacaにログイン後、ダッシュボードから新規プロジェクトを作成します。
その際、テンプレートとして「最小限のプロジェクト」を選択します。

【必要ライブラリの入手と設置】
・zepto.js
http://zeptojs.com/
→ zepto.min.jsを「www/js」フォルダに配置します。

・JavaScript QRCode reader by LazarSoft
https://github.com/LazarSoft/jsqrcode
→ QRCode.jsなど全てのjsファイルを「www/js/qr」フォルダに配置します。

【アプリのソースコード】
あとは以下のコードを貼り付けていけばアプリ完成です!

◆www/index.html : メイン画面です。ツールバーは後述のindex.uiファイルで定義します。


<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>QR Code Reader</title>
  <script src="plugins/plugin-loader.js"></script>
  <script>
    monaca.viewport({width: 240});
  </script>
  <script src="js/qr/grid.js"></script>
  <script src="js/qr/version.js"></script>
  <script src="js/qr/detector.js"></script>
  <script src="js/qr/formatinf.js"></script>
  <script src="js/qr/errorlevel.js"></script>
  <script src="js/qr/bitmat.js"></script>
  <script src="js/qr/datablock.js"></script>
  <script src="js/qr/bmparser.js"></script>
  <script src="js/qr/datamask.js"></script>
  <script src="js/qr/rsdecoder.js"></script>
  <script src="js/qr/gf256poly.js"></script>
  <script src="js/qr/gf256.js"></script>
  <script src="js/qr/decoder.js"></script>
  <script src="js/qr/QRCode.js"></script>
  <script src="js/qr/findpat.js"></script>
  <script src="js/qr/alignpat.js"></script>
  <script src="js/qr/databr.js"></script>
  <script src="js/zepto.min.js"></script>
  <script src="js/index.js"></script>
  <link rel="stylesheet" href="css/style.css">
</head>
<body>
<p id="ResultMessage">
  Cameraボタンから写真を撮るか、Albumボタンから写真を選択してください。
</p>
<input id="BrowserOpenButton" type="button" value="ブラウザで開く" style="display: none;">
<div class="img-area">
  <img id="PreviewImage" src="" alt="">
</div>
</body>
</html>

◆www/index.ui : Monacaのネイティブコンポーネント機能を使ってツールバーを定義します。


{
  "top": {
    "container": "toolbar",
    "style": {
      "title": "QR Code Reader",
      "backgroundColor": "#333333"
    },
    "left": [
      {
        "component": "button",
        "id": "CameraButton",
        "style": {
          "text": "Camera",
          "disable": "true"
        },
        "event": {
          "onTap": "getQRCode('camera')"
        }
      }
    ],
    "right" : [
      {
        "component": "button",
        "id": "AlbumButton",
        "style": {
          "text": "Album",
          "disable": "true"
        },
        "event": {
          "onTap": "getQRCode('album')"
        }
      }
    ]
  }
}

◆www/js/index.js : このように思いつきでサクっと作れるのがJSアプリの良い所ですね。


$(function() {
  
  // PhoneGapの初期化後にヘッダのボタンを有効化するため
  document.addEventListener("deviceready", onDeviceReady, false);
  
  // ブラウザで開くボタンのイベント
  $("#BrowserOpenButton").click(function() {
    // invokeBrowserを用いてブラウザでURLを開く
    monaca.invokeBrowser($("#ResultMessage").text());
    return false;
  });
});
//////////////////////////// onDeviceReady
function onDeviceReady() {
  monaca.updateUIStyle("CameraButton", "disable", "false");
  monaca.updateUIStyle("AlbumButton", "disable", "false");
}
//////////////////////////// getQRCode
function getQRCode(type) {
  // カメラとアルバムのどちらを対象にするか決める
  var srcType = (type == "camera") ? Camera.PictureSourceType.CAMERA : Camera.PictureSourceType.PHOTOLIBRARY;
  // 結果画面をリセット
  $("#ResultMessage").text("");
  $("#BrowserOpenButton").hide();
  $("#PreviewImage").attr("src", "");
  // PhoneGapを利用して画像を得る
  navigator.camera.getPicture(
    // success
    function(imagePath) {
      // imagePathに画像ファイルパスがセットされている
      $("#PreviewImage").attr("src", imagePath);
      $("#ResultMessage").text("デコード中です...");
      
      // QRコード取得時のコールバックを設定
      qrcode.callback = function(result) {
        // QRコード取得結果を表示
        $("#ResultMessage").text(result);
        if (result.indexOf("http") === 0) {
          // URLであれば開くボタンを表示
          $("#BrowserOpenButton").show();
        }
      };
      
      // QRコード取得開始
      qrcode.decode(imagePath);
    },
    // error
    function(errorMsg) {
      $("#ResultMessage").text(errorMsg);
    },
    // params
    {
      sourceType: srcType,
      destinationType: Camera.DestinationType.FILE_URI,
      encodingType: Camera.EncodingType.PNG,  // PNG形式
      targetWidth: 200,  // 縮小サイズは要調整
      targetHeight: 200
    }
  );
}

◆www/css/style.css


* {
  margin: 0;
  padding: 0;
}
body {
  font-size: 90%;
  text-align: center;
  color: #222;
  background: #FFF;
  padding: 0 10px;
}
#ResultMessage,
.img-area {
  margin: 15px 0;
}

【参考ドキュメント】
・Apache Cordova API Documentation
http://docs.phonegap.com/jp/2.0.0/

・Monacaドキュメント
http://docs.monaca.mobi/