Monacaでは、スマートフォンやタブレットの持つセンサーから値を取得してアプリ開発に利用することができます。

今回はカメラ機能で写真を撮ったり、端末内部の写真データを取得する方法を紹介します。

なお、デジカメやスマートフォンのカメラの内部には光を感知するセンサーがあり、それによって写真を撮っています。

Monacaで学ぶはじめてのプログラミング(初版)利用者向けの注意事項

OSのアップデートにより端末内部の写真ファイルのアクセスに変更があり、初版の記事の方法では取得できないケースが発生しました。
BASE64方式であれば取得ができるため、現在はBASE64方式を紹介しています。

ファイル方式とBASE64方式の違い

BASE64はファイルを文字列に置き換えた形式です。

OSによっては端末内部のファイルを直接画像としてimgタグで参照することを許可していないケースがあり、その場合は初版のやり形で端末内部の写真を表示することができません。

BASE64方式では端末内部の写真をファイルではなく、文字列に置き換えたデータ(BASE64)として取得します。

写真の文字列はimgタグの属性値に設定することができ、それによって写真を表示することができます。

BASE64方式の制限

ファイルのサイズが大きいと上手く動かない場合があります。そのため、本記事ではファイルサイズを小さくするために品質のパラメーターを低めに設定しています。

ブラウザで大きなファイルを扱いたい場合には、File APIやFileReader APIの利用を検討して下さい。

諸注意

  • モバイル端末のハードウェア機能を呼び出すため、MonacaIDEのプレビューでは動作しません。
  • スマートフォンやタブレットにデバッガーアプリ(Monaca for Study)をインストールして動かしてください。
  • 呼び出しにはアプリ内で準備が必要なため、deviceready イベントを考慮する必要があります。
  • 今回のサンプルではファイルサイズを小さくするために品質のパラメーターを低めに設定しています
  • 画像の表示にBASE64方式を

devicereadyの使用

モバイル端末のハードウェア機能を呼び出すため、MonacaIDEのプレビューでは動作しません。デバッガーアプリをご用意ください。また、ハードウェア機能の呼び出しにはアプリ内で準備が必要なため、deviceready イベントを考慮する必要があります。

サンプルアプリ

カメラ機能 ひな形

カメラ機能 完成版

ひな形版のソースコード

ひな形ではHTML部分と関数の定義、それとカメラ呼び出し時の品質や取得形式のパラメーターだけが記載されています。
完成版に持って行くためには、scriptタグ内に完成版のソースコードを打ち込みます。

完成版のソースコード


<script>
// 写真を撮る
function takePicture() {
    var options = {
        sourceType: Camera.PictureSourceType.CAMERA,   // 撮影モード
        saveToPhotoAlbum: true,   // 撮影後、写真を端末に保存
        destinationType : Camera.DestinationType.DATA_URL, 
        quality :30, 
    };
    // カメラを起動
    navigator.camera.getPicture(onSuccess, onError, options);
    // 撮影完了したときに呼び出される
    function onSuccess(DATA_URL){
        alert("画像を保存しました");
        document.getElementById("photo").src = "data:image/jpeg;base64," + DATA_URL;
    }
    // 撮影キャンセルしたときに呼び出される
    function onError(message){
        alert("エラー: " + message);
    }
}
// 写真を見る
function loadPicture() {
    var options = {
        sourceType: Camera.PictureSourceType.SAVEDPHOTOALBUM,   // 撮影モード
        destinationType : Camera.DestinationType.DATA_URL, 
        quality :30, 
    };
    // カメラを起動
    navigator.camera.getPicture(onSuccess, onError, options);
    // 撮影完了したときに呼び出される
    function onSuccess(DATA_URL){
        document.getElementById("photo").src = "data:image/jpeg;base64," + DATA_URL;
    }
    // 撮影キャンセルしたときに呼び出される
    function onError(message){
        alert("エラー: " + message);
    }
}
</script>
</head>
<body>
    <div id="buttons">
        <button onclick="takePicture()">写真を撮る</button>
        <button onclick="loadPicture()">写真を見る</button>
    </div>
    <img id="photo" src="">
</body>

解説

takePicture()

この関数ではnavigator.camera.getPicture()関数を使ってカメラを呼び出します。

カメラを呼び出すときの諸条件はoptions変数で予め定義しています。また、カメラを呼び出したときの処理に関してはonSuccess()関数が、呼び出し失敗したときにはonError()関数を呼ぶように記述しています。

今回のオプションはカメラを通常モードで起動して撮影後に端末に保存する設定(saveToPhotoAlbum: true)となっています。端末に保存する必要が無い場合は「saveToPhotoAlbum: false」に設定してください。また、オプションで起動するカメラをリアカメラに変更することも可能です。オプションで指定できる内容の詳細はCordovaのマニュアルを参照してください。

カメラの撮影が成功したときに取得できる情報

「function onSuccess(imageURI){」の引数部分が、カメラの撮影が成功したときに取得できる情報を示しています。端末内で写真が保存された場所のアドレス情報が格納されます。

この情報をimgタグのsrc属性に渡せば、画面上に画像を表示できます。

loadPicture()

この関数もnavigator.camera.getPicture()関数を使っているのですが、オプションで「Camera.PictureSourceType.SAVEDPHOTOALBUM」を指定しています。この場合、カメラが起動する代わりに端末内に保存された写真を参照します。アプリの利用者には写真の一覧が表示され、そのなかかから写真を選んで貰う形となります。

アプリの利用者が写真を選んでくれた場合はonSuccess()関数、選んでくれなかった場合はonError()関数が呼ばれます。