このページの本文へ

Android 4の新機能でカメラWebアプリ作ってみた (4/5)

2012年04月04日 10時01分更新

文●古籏一浩

  • この記事をはてなブックマークに追加
本文印刷

カメラで撮影した画像をCanvasに描画する

 img要素で読み込んだ画像はJavaScriptでサイズを変更したり加工したりできません。そのため、File APIで読み込んだ画像はimg要素ではなくCanvas要素に描画してJavaScriptで操作できるようにします。

 画像を表示するためのcanvas要素をあらかじめ用意しておきます。


<canvas id="myCanvas" width="240" height="320" style="border:1px solid black"></canvas>

 File APIで読み込んだ画像をCanvasに描画するには、画像オブジェクトのsrcに画像ファイルの内容を入れます。ただし、非同期で処理されるため、srcプロパティに画像を入れた直後にdrawImage()メソッドを実行しても期待どおりの結果を得られません。

 そのため、画像ファイルが完全に処理された後にCanvasに描画する必要があります。画像オブジェクトのonloadプロパティにイベントハンドラを設定し、その中でdrawImage()を使ってCanvasに画像を描画します。

 実際のプログラムはサンプル3です。カメラで撮影した画像がCanvasに描画されます。

【図】fig9.png

四角い枠がCanvas領域。「ファイルを選択」ボタンをタップするとカメラが起動する

【図】fig10.png

カメラで撮影する

【図】fig11.png

撮影した画像がCanvas内に描画される

■サンプル3


<!DOCTYPE html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content= "initial-scale=1">
    <title>カメラから取り込みCanvasに描画する</title>
  </head>
  <body>
    <h1>カメラから取り込みCanvasに描画する</h1>
    <form>
      <input type="file" accept="image/*;capture=camera" id="cameraImage">
    </form>
    <canvas id="myCanvas" width="240" height="320" style="border:1px solid black"></canvas>
    <script>
      // 撮影後に処理を開始
      document.getElementById("cameraImage").addEventListener("change", function(){
        // Canvasにカメラで撮影した画像を描画
        var canvasObj = document.getElementById("myCanvas");
        var context = canvasObj.getContext("2d");
        var canvasW = canvasObj.width;
        var canvasH = canvasObj.height;
        var reader = new FileReader();
        reader.onload = function(evt){
          var imgObj = new Image();
          imgObj.src = reader.result;
          imgObj.onload = function(){
            context.drawImage(imgObj,0,0, canvasObj.width, canvasObj.height);
          }
        }
        var imageFile = document.getElementById("cameraImage").files[0];
        reader.readAsDataURL(imageFile);
      }, false);
    </script>
  </body>
</html>

Canvas内容を読み出す

 iOSではCanvas内の画像データはtoDataURL()メソッドを使って読み出せました。Android 2ではtoDataURL()メソッドに対応していませんでしたが、Android 4からiOS同様に利用できるようになりました。

 toDataURL()メソッドを利用できれば、Canvasに描画した画像をローカルストレージに保存したり、サーバーにアップロードしたりもできます。

 サンプル4は撮影した画像をCanvasに描画した後、Canvas内の画像データをtoDataURL()メソッドを使って読み出しています。最初にバイト数がアラートダイアログに表示され、その後、ページ内に画像内容がdata:形式で表示されます。なお、toDataURL()メソッドの引数には保存形式を指定できますが、Android 4 (Galaxy Nexus) ではPNG形式にのみ対応しているようです。

【図】fig12.png

撮影した画像のサイズ(文字数)がアラートダイアログに表示される

【図】fig13.png

Canvas内容を読み出した結果がdata:形式として画面に表示される

■サンプル4


<!DOCTYPE html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content= "initial-scale=1">
    <title>カメラから取り込みCanvasに描画する(2)</title>
  </head>
  <body>
    <h1>カメラから取り込みCanvasに描画する(2)</h1>
    <form>
      <input type="file" accept="image/*;capture=camera" id="cameraImage">
    </form>
    <canvas id="myCanvas" width="240" height="320" style="border:1px solid black"></canvas>
    <div id="result">---</div>
    <script>
      // 撮影後に処理を開始
      document.getElementById("cameraImage").addEventListener("change", function(){
        // Canvasにカメラで撮影した画像を描画
        var canvasObj = document.getElementById("myCanvas");
        var context = canvasObj.getContext("2d");
        var canvasW = canvasObj.width;
        var canvasH = canvasObj.height;
        var reader = new FileReader();
        reader.onload = function(evt){
          var imgObj = new Image();
            imgObj.src = reader.result;
            imgObj.onload = function(){
            context.drawImage(imgObj,0,0, canvasObj.width, canvasObj.height);
            var data = canvasObj.toDataURL();
            alert(data.length);
            document.getElementById("result").innerText = data;
          }
        }
        var imageFile = document.getElementById("cameraImage").files[0];
        reader.readAsDataURL(imageFile);
      }, false);
    </script>
  </body>
</html>

この連載の記事

一覧へ

この記事の編集者は以下の記事をオススメしています