プラグインを利用したサンプルアプリ
続いて、図2のようなサンプルアプリを作成します。どちらのボタンを押してもgetPictureメソッドを呼び、選択した画像がIMGタグとして表示されます。「起動」ボタンを押すと、カメラを起動した後、base64データにてデータを取得し、下の「選択」ボタンでは各種プロパティの値を変更して、getPictureメソッドを呼べるようにしています。
リスト7は、データをbase64形式で取得したときに、IMG要素に画像を表示するためのサンプルコードです。
// (1) 起動時のオプション
var cameraOptions = {
cameraDirection : Camera.Direction.BACK, // (2) 起動後に選べる
destinationType : Camera.DestinationType.DATA_URL, // (3) base64形式を指定
encodingType : Camera.EncodingType.JPEG,
targetWidth : 360,
targetHeight: 480,
};
$scope.camera = function(){
navigator.camera.getPicture(function(result){
$scope.$apply(function(){
// (4) 取得したデータをBase64のデータの画像として表示
var src = "data:image/jpeg;base64," + result;
$('#image').attr('src',src);
});
},function(message){
$scope.$apply(function(){
// (5) エラーメッセージを表示
$scope.message = "error :" + message;
});
},cameraOptions);
};
(1)ではオプションではカメラ起動時のオプションを指定しています。そのオプションの中で(2)のようにカメラとして背面を指定していますが、Androidの場合にはFRONTを指定しても有効になりません。
また、どちらを指定しても画面上では利用者が変更可能です。また、(3)では取得データ形式をbase64形式に指定していますので、(4)で取得できるデータもbase64の文字列になります。この文字列をもとに、IMGタグ内にインラインで埋め込めるデータ(DATA_URL)を作成することができます。このようにDATA_URL形式を利用することで、OSの動作に依存しないコードの記述が可能です。ただし、データが大きいと、結果として返る文字列データも大きくなるので注意が必要です。
その場合はリスト8で示すように、FILE_URI形式でデータを取得する方が望ましいです。しかし、OSごとに返るパスのスキーム形式などが変わるため、多少の考慮が必要となります。また、このコードはHTML上からオプションを指定できるようになっていますので、実際にどのようなパスが返るのか、また、どのような動作に変わるのかを確認できるコードになっています。
// (1) デフォルトのオプションを指定(画面上から変更可能)
$scope.sourceType = String(Camera.PictureSourceType.PHOTOLIBRARY);
$scope.mediaType = String(Camera.MediaType.ALLMEDIA);
$scope.encodingType = String(Camera.EncodingType.JPEG);
$scope.cameraDirection = String(Camera.Direction.BACK);
$scope.select = function(){
$scope.message = null;
navigator.camera.getPicture(function(result){
$scope.$apply(function(){
$scope.path = result;
// (2) Androidの場合でかつcontent://から始まる場合の対応
if (result.indexOf('content://') != -1) {
window.FilePath.resolveNativePath(result, function(path){
$('#image').attr('src',path);
},function(err){
});
}
// : 省略
});
},function(message){
// : 省略
},{
// (3) 取得をFILE_URIに変更
destinationType: Camera.DestinationType.FILE_URI,
sourceType : Number($scope.sourceType),
mediaType : Number($scope.mediaType),
encodingType : Number($scope.encodingType),
cameraDirection : Number($scope.cameraDirection)
});
}
(1)ではAngularJSの機能を使って画面上のSELECT要素で変更した値とのバインディングを行っています。そして(2)では返ってきたパスがcontent://から始まる場合に前述したFilePathプラグインを使ってパス名を変更しています。これは、そのままIMG要素に指定してもデータが表示されないためです。また、(3)では結果をFILE_URIで取得するための設定をしています。
実際のパラメータの変更によりどのように動作が変わるのは説明だけではわかりにくいので、実際のサンプルコードを実行してみることをおすすめします。
その他、アルバムから選択するプラグイン
iOSの場合、画像やビデオを扱う場所としてカメラロールのように共通して扱うことができますが、Androidの場合は画像として取得できる場所が多く、PHOTOLIBRARYを指定すると図3(左)のような画面が表示されます。
スマホの操作に詳しい方であれば問題ないかもしれませんが、カメラで撮った写真の中から選択させたい場合などには少々困るケースがあるかもしれません。従って、iOSと同じようにすぐ写真などを選択できる画面が表示されてほしい場合はcordova-plugin-imagepickerプラグインがあります。
このプラグインを使うと図3(右)のようにすぐに画像が表示され、余計なメニューなどは表示されません。もし、興味があるかたはサンプルコードの中に含まれているので参照してみてください。ただし、現時点では文言が英語でコード内に記述されている部分があるため変更ができません。また、筆者がiPadで試した場合にはアプリが落ちてしまいました。そのため、現時点で利用する場合には少々、注意が必要です。
最後に
既存のWebアプリの延長線上としてカメラや写真をあつかう場合、今回紹介したプラグインは大いに活用できます。特に、写真データをクラウド側のサービスへアップロードするといった用途に向いています。一方、カメラの制御や写真データの加工などを自由に行いたい場合、Cordova(WebView上)には少々難しい領域です。
自分のニーズに合うようなプラグインもほとんどないことでしょう。そのため、その部分だけ実際にはネイティブで記述しなければならないケースもあるかもしれません。もし、そのようなケースが生じた場合には今回紹介したプラグインのソースを参考にすると、よりいっそうCordovaへの理解が深まることと思います。
次回からは、連絡先やカレンダーといったスマートフォン内の個人データを扱うプラグインを紹介します。
