カメラで撮影した画像を処理する
次に、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>
実際のプログラムはサンプル4です。Xcodeでビルドした後、実機に転送して動作を確認します。ボタンをタップするとカメラが起動し、写真を撮影すると、Canvasに画像が表示されます。画像フィルタボタンをタップするとグレースケールに変換されます。
■サンプル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のように高速では処理できません。速度が低下するデメリットも踏まえて上手に活用したいところです。