スマートフォンにとってカメラはとても大事な機能です。多くのアプリでカメラ機能が使われています。Twitterのようなソーシャルアプリでの投稿に使ったり、InstagramやTikTokのようにカメラ機能がメインのアプリもあります。ジョギング、Todoアプリなど一見すると写真は関係なさそうなアプリであってもカメラ機能が使われていたりします。
Monacaアプリでカメラ機能を実装する際に使われるのがカメラ操作 プラグインになります。カメラ機能を活かすためにも、ぜひ使い方を覚えましょう。
インストール
カメラ操作プラグインを使う際には、Monaca IDEのCordovaプラグインの管理より、Cameraプラグインを有効にしてください。
また、config.xmlの中にある下記項目を編集します。これはiOS向けの設定になります。
<!-- カメラを起動して写真を撮影する際のメッセージを記述します -->
<edit-config target="NSCameraUsageDescription" file="*-Info.plist" mode="merge">
<string>need camera access to take pictures</string>
</edit-config>
<!-- フォトライブラリから写真を取得する際のメッセージを記述します -->
<edit-config target="NSPhotoLibraryUsageDescription" file="*-Info.plist" mode="merge">
<string>need to photo library access to get pictures from there</string>
</edit-config>
<!-- フォトライブラリに写真を保存する際のメッセージを記述します -->
<edit-config target="NSPhotoLibraryAddUsageDescription" file="*-Info.plist" mode="merge">
<string>need to photo library access to save pictures there</string>
</edit-config>
これらのメッセージは、アプリでその機能を利用する際に一度だけ表示されるものです。分かりやすい説明で、なぜアクセス許可が必要かを記述しましょう。
使い方
基本的な使い方は次のようになります。 successCallback
は写真データの取得成功した際に呼ばれる関数、 errorCallback
は処理失敗した時に呼ばれる関数、options
は設定情報です。
navigator.camera.getPicture(successCallback, errorCallback, options);
この形式だと、コールバック地獄になりがちなので、ラッピングすると使いやすくなります。例えばこんな感じの関数を定義しましょう。
function getPicture(options = {}) {
return new Promise((res, rej) => {
navigator.camera.getPicture(res, rej, options);
});
}
この getPicture
関数であれば、次のように呼び出せます。
document.querySelector('#camera').addEventListener('click', async (e) => {
e.preventDefault();
const photo = await getPicture();
document.querySelector('#photo').setAttribute('src', photo);
});
得られる結果について
デフォルトのまま使った場合、返ってくるのは以下のような写真のURIになります。
file:///var/mobile/Containers/Data/Application/FF...DC/tmp/cdv_photo_001.jpg
つまりこのURIをそのままimgタグのsrc要素に適用すれば画像が表示できます。この他、BASE64エンコードされた文字列としてデータを取得することもできます。その場合、オプションとして destinationType
を Camera.DestinationType.DATA_URL
と指定します。これで返値の形式がURIではなく、文字列になります。
{
destinationType: Camera.DestinationType.DATA_URL
}
なお、最近のスマートフォンで撮影した写真は高画質であり、ファイルサイズも大きくなります。文字列データも大きくなりやすく、メモリエラーを起こす可能性があります。従って文字列での取得はあまりお勧めしません。文字列の場合は、次のように data:image/jpeg
を付けて表示できます。
const photo = await getPicture();
document.querySelector('#photo').setAttribute('src', data:image/jpeg;base64,${photo}
);
写真の取得元を指定
写真の取得元はカメラとフォトライブラリの二つが考えられます。これは sourceType
オプションで指定できます。以下の三つを使い分けます。
- Camera.PictureSourceType.PHOTOLIBRARY
写真のライブラリー - Camera.PictureSourceType.CAMERA
カメラ - Camera.PictureSourceType.SAVEDPHOTOALBUM
カメラロール
例えば次のようになります。
{
sourceType: Camera.PictureSourceType.CAMERA
}
写真の品質
カメラで撮影した場合に、写真の品質を指定できます。これは quality
オプションを使います。指定できるのは0〜100で、0に近いほどサイズが小さく(画質は粗く)なります。
{
quality: 50
}
写真撮影後に簡易的な編集を行う
allowEdit
オプションを使うと、写真撮影後に拡大、縮小といった簡易的な画像編集が行えます。
{
allowEdit: true
}
画像フォーマットを指定する
encodingType
を使ってPNG画像として取得できるようになります。デフォルトはJPEGです。
{
encodingType: Camera.EncodingType.PNG
}
画像のサイズを指定する
取得する画像サイズを指定できます。これは targetWidth
と targetHeight
で指定できます。例えば500x500で取得するといった指定が可能です。
{
targetWidth: 500,
targetHeight: 500
}
画像の向きを補正
correctOrientation
を使って、取得した際の端末の向きと同じ向きに写真を補正します。
{
correctOrientation: true
}
写真を撮影した後、保存する
saveToPhotoAlbum
を true にすると、カメラで撮影した写真をアルバムに保存してくれます。
{
saveToPhotoAlbum: true
}
前面または背面のカメラを指定
cameraDirection
は前面または背面のカメラを指定します。Camera.Direction.FRONTで前面、Camera.Direction.BACK で背面のカメラを利用します。
{
cameraDirection: Camera.Direction.FRONT
}
iPadでのポップオーバーの表示位置を指定
これはiPadだけで使われるUIで、ポップオーバーの表示位置を指定します。ちょっとパラメータが多いです。詳細はカメラ操作 プラグイン | Monaca Docsを参考にしてください。
{
popoverOptions: new CameraPopoverOptions(300, 300, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY)
}
HTML5のinput#fileとの違い
HTML5では input type=file
が強化されており、iPhoneからカメラを起動したり、フォトライブラリから写真を取得することもできるようになっています。このカメラ操作 プラグインとの違いはどこにあるでしょうか。
カスタマイズのしやすさ
まず第一にカメラ操作 プラグインの方が細かくカスタマイズできます。HTML5標準の場合、最初にカメラを起動するか、フォトライブラリを起動するかという指定と、動画または写真だけという指定はできます。しかし、その二つくらいしかオプションがありません。
カメラ操作 プラグインの場合、写真のサイズや品質を指定できます。これをHTML5で行う場合FileReaderやCanvasで加工する必要があります。カメラ操作 プラグインでは、これらをネイティブ側で行った上で写真データだけを返してくれるので便利です。
画像の回転
iPhoneで写真を撮影してHTML5上でプレビュー表示した場合、回転してしまう問題が知られています(via iPhoneからアップロードしたJPEG写真が横向きになる問題(EXIF, Orientation) - Qiita)。これを解決するためには写真のメタデータであるEXIFを読み込んで回転情報であるOrientationに基づいてCanvas内で描画し直す必要があります。カメラ操作 プラグインで試してみた限り、そのような問題は起こらないようです。これは大きなメリットといえます。
クラウド上のファイルの利用
HTML5の場合、ファイル選択ダイアログでクラウドサービス(iCloud、Dropboxなど)も選択肢に入ってきます。カメラ操作 プラグインの場合、基本的にカメラまたはデバイス内のデータを対象としますので、外部サービスから写真を取得する場合には不向きです。
手軽さ
Cordovaプラグインを使うことに比べ、手軽さでいえばHTML5の方が楽かも知れません。単にファイルを選択してアップロードするだけというのであれば、プラグインを使うのは大げさというケースもあるでしょう。
まとめ
カメラ操作 プラグインを使えばカメラやデバイス内部の写真データを手軽に扱えるようになります。特に簡易的な加工ができることで、これまでJavaScriptで記述していた面倒な内容がプラグインに任せられるようになるのはとても便利です。ぜひ使いこなしてください。