このページの本文へ

PROGRAMMING 古籏一浩のJavaScriptラボ第82回

iOS 5で使えるWeb Workersでカメラアプリ作ってみた

2012年02月22日 11時00分更新

古籏一浩

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

カメラで撮影した画像を処理する

 次に、PhoneGapを使ってカメラで撮影した画像を取り込み、グレースケールに変換してみましょう。

 カメラから画像を取り込むには、PhoneGap独自のCamera APIを利用する方法と、Capture APIを利用する方法がありますが、今回はCapture APIを利用します。Capture APIでは、navigator.device.capture.captureImage()メソッドを使ってカメラから画像を取り込みます。

 取り込んだ画像をCanvasに描画してしまえば、後はこれまでと同じです。PhoneGapのAPIを使用していますので、必ず以下のscript要素を追加してください。


<script type="text/javascript" charset="utf-8" src="phonegap-1.2.0.js"></script>
【図】fig12.png
PhoneGapを使うためのscript要素を忘れずに追加する

 実際のプログラムはサンプル4です。Xcodeでビルドした後、実機に転送して動作を確認します。ボタンをタップするとカメラが起動し、写真を撮影すると、Canvasに画像が表示されます。画像フィルタボタンをタップするとグレースケールに変換されます。

【図】fig13.jpg
「カメラから取り込み」ボタンをタップ
【図】fig14.jpg
カメラが起動するので撮影する
【図】fig15.jpg
撮影した画像を使用する場合は「Use」ボタンをタップ。再度撮影し直す場合は「Retake」ボタンをタップする
【図】fig16.jpg
Canvasに撮影した画像が表示される。「画像フィルタ」ボタンをタップすると画像がグレースケールに変換される
【図】fig17.jpg
ワーカーでの処理が終わるとアラートダイアログが表示される
【図】fig18.jpg 【図】fig19.jpg
撮影した画像がグレースケールに変換される

■サンプル4 ※effect.jsはサンプル3と同じ


<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content= "initial-scale=1">
    <title>画像フィルタ</title>
    <script type="text/javascript" charset="utf-8" src="phonegap-1.2.0.js"></script>
  </head>
  <body>
    <h1>画像フィルタ</h1>
    <form>
      <input type="button" id="capture" value="カメラから取り込み">
      <input type="button" id="effect" value="画像フィルタ">
    </form>
    <canvas id="myCanvas" width="500" height="750" style="border:1px solid black"></canvas>
    <script>
      var canvasObj = document.getElementById("myCanvas");
      var context = canvasObj.getContext("2d");
      var canvasW = canvasObj.width;
      var canvasH = canvasObj.height;
      // クリックしたらエフェクト処理を開始
      document.getElementById("capture").addEventListener("click", function(){
        // Capture APIで写真撮影
        navigator.device.capture.captureImage(
          function(mediaFiles) {
            // Canvasに撮影したカメラ画像を描画
            var imgObj = new Image();
            imgObj.src = mediaFiles[0].fullPath;  // 画像のURLを指定
            imgObj.onload = function(){
              context.drawImage(imgObj,0,0, canvasObj.width, canvasObj.height);
            }
          }, 
          function(error) {
            alert("Error !!:"+error.code);
          }
        );
      }, false);
      // クリックしたらエフェクト処理を開始
      document.getElementById("effect").addEventListener("click", function(){
        var imageData = context.getImageData(0,0, canvasObj.width, canvasObj.height);
        // ワーカー生成&イベント設定
        var effectWorker = new Worker("effect.js");
        var counter = 0;  // 処理すべきY座標の値
        var pixelData = new Array();  // ワーカーで処理するピクセルを入れる配列
        var outputData = context.createImageData(canvasW, 1);
        effectWorker.addEventListener("message", function(event){
          // ワーカーから渡されたピクセルを配列にコピー
          for(var i=0; i<event.data.length; i++){
            outputData.data[i] = event.data[i];
          }
          context.putImageData(outputData, 0, counter);
          counter = counter + 1;
          if (counter < canvasH){
            // ピクセルデータを配列にコピーする
            var startPoint = (canvasW * 4) * counter; // ピクセルの処理を行う配列の位置を求める
            for(var i=0; i<canvasW*4; i++){
              pixelData[i] = imageData.data[startPoint + i];
            }
            // ワーカーのエフェクト処理を実行
            effectWorker.postMessage({
              pixels: pixelData,  // ピクセルデータ(配列)
              width: canvasW  // Canvasの横幅
            });
          }else{
            alert("完了しました");
          }
        }, true);
        // ピクセルデータを配列にコピーする
        var pixelData = new Array();
        for(var i=0; i<canvasW*4; i++){
          pixelData[i] = imageData.data[i];
        }
        // ワーカーのエフェクト処理を実行
        effectWorker.postMessage({
          pixels: pixelData,  // ピクセルデータ(配列)
          width: canvasW  // Canvasの横幅
        });
      }, false);
    </script>
  </body>
</html>

 Web Workersは便利な機能ですが、iOS5(iPhone)ではPCのように高速では処理できません。速度が低下するデメリットも踏まえて上手に活用したいところです。

Web Professionalトップへ

この連載の記事

一覧へ
Web Professionalトップページバナー

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

ASCII.jp会員サービス 週刊Web Professional登録

Webディレクター江口明日香が行く