Camera プラグイン

テスト環境 ( バージョン番号 ) : 5.0.1

このプラグインの詳細は、こちら ( GitHub ) をご確認ください。

このプラグインでは、グローバルオブジェクト 「 navigator.camera 」 の API を使用し、 システム側の画像ライブラリーからの画像の取得、および、写真撮影を行います。

このオブジェクトは、グローバルスコープ ( navigator ) に属しています。 使用できるのは、 deviceready イベントの発火後になります。

document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
    console.log(navigator.camera);
}

プラグイン ID

cordova-plugin-camera

プラグインの追加方法

このプラグインを使用する場合には、Monaca クラウド IDE の [ Cordova プラグインの管理 ] 上で、Camera プラグインを有効にします。

iOS 特有の動作

iOS 10以降、プライバシーに関連するデータにアクセスする場合は、 info.plist に使用の説明を設定することが必須になります。アクセスを許可するようにシステムに指示すると、この使用の説明はアクセス許可ダイアログボックスの一部として表示されますが、使用の説明を入力しない場合は、ダイアログが表示される前にアプリが強制終了します。また、Apple は個人データにアクセスするアプリをリジェクトしますが、使用の説明は提供していません。

このプラグインでは、次の使用の説明が必要になります。

  • NSCameraUsageDescription には、アプリがユーザーのカメラにアクセスする理由を記述します。

  • NSPhotoLibraryUsageDescription には、アプリがユーザーの写真ライブラリにアクセスする理由を記述します。

  • NSLocationWhenInUseUsageDescription には、アプリがユーザーの位置情報にアクセスする理由を記述します。 (CameraUsesGeolocation が true に設定されている場合に設定します)

  • NSPhotoLibraryAddUsageDescription には、アプリがユーザーの写真ライブラリに書き込みアクセスを許可する理由を記述します。

これらの設定を info.plist に追加するには、config.xml ファイルの <edit-config> タグに以下のように設定します。

<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="NSLocationWhenInUseUsageDescription" file="*-Info.plist" mode="merge">
    <string>need location access to find things nearby</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>

API の解説

Camera

camera.getPicture(successCallback, errorCallback, options)

カメラでの写真撮影、または、端末の画像ギャラリーから、画像を取得します。画像は、Base64 形式の 文字列 として、または、画像ファイルを指す URI として、成功時のコールバック関数に引き渡されます。

camera.getPicture 関数では、端末にインストールされている標準のカメラアプリを起動させます ( Camera.sourceTypeCamera.PictureSourceType.CAMERA に設定されている場合の動作 )。写真撮影後は、カメラアプリが終了し、使用していたアプリ ( カメラアプリの起動前になんらかのアプリを使用していた場合 ) が開きます。

Camera.sourceTypeCamera.PictureSourceType.PHOTOLIBRARY、または、Camera.PictureSourceType.SAVEDPHOTOALBUM の場合、画像選択用のダイアログが表示され、既存の画像があれば、その中から選択できます。

戻り値は、cameraSuccess コールバック関数に渡されます。戻り値は、 cameraOptions の設定に応じて、次のいずれかの形式で返されます。

  • 文字列 : Base64 形式でエンコードされた写真画像

  • 文字列 : 画像ファイルの保存場所 ( ローカルのストレージ内、デフォルトはこちら )

上記の値 ( エンコードされた画像、または、URI ) を使用して、次のような、さまざまな処理ができます。

  • <img> タグ内への画像のレンダリング ( このページ内にサンプルがあります )

  • ローカルへのデータの保存 ( LocalStorageLawnchair など )

  • 外部サーバーへのデータの送信

最新の端末で撮影した写真の解像度は高くなります。端末のギャラリーから取得する画像は、 quality パラメーターで画質を指定しても、解像度の低い画像に変換されません。メモリー問題を回避するためには、Camera.destinationType を、 DATA_URL ではなく、 FILE_URI に設定します。

対象プラットフォーム

  • Android

  • iOS

例は こちら。 各 OS 特有の動作は こちら

navigator.camera.getPicture(cameraSuccess, cameraError, cameraOptions);

camera.cleanup()

camera.getPicture を呼び出した後に取得し、一時的なストレージに保存されている処理前の画像ファイルを削除します。Camera.sourceType の値と Camera.PictureSourceType.CAMERA が等しく、また、 Camera.destinationTypeCamera.DestinationType.FILE_URI と等しい場合のみ有効です。

対象プラットフォーム

  • iOS

navigator.camera.cleanup(onSuccess, onFail);

function onSuccess() {
    console.log("Camera cleanup success.")
}

function onFail(message) {
    alert('Failed because: ' + message);
}

camera.onError

エラーメッセージを出力するコールバック関数です。

camera.onSuccess

画像データを返すコールバック関数です。

// Show image
//
function cameraCallback(imageData) {
   var image = document.getElementById('myImage');
   image.src = "data:image/jpeg;base64," + imageData;
}

camera.CameraOptions

カメラの設定をカスタマイズするオプションのパラメーターです。

プロパティ

Camera

Camera.DestinationType

Camera.getPicture の出力形式を定義します。

iOSでは、 DestinationType.NATIVE_URIPictureSourceType.PHOTOLIBRARY または PictureSourceType.SAVEDPHOTOALBUM を渡した場合、仕様により画像の変更(サイズ変更、品質の変更、切り取りなど)が無効になります。

プロパティ

Camera.EncodingType

プロパティ

Camera.MediaType

プロパティ

Camera.PictureSourceType

Camera.getPicture の出力形式を定義します。

iOSでは、DestinationType.NATIVE_URIPictureSourceType.PHOTOLIBRARY または PictureSourceType.SAVEDPHOTOALBUM を渡した場合、仕様により画像の変更(サイズ変更、品質の変更、切り取りなど)が無効になります。

プロパティ

Camera.PopoverArrowDirection

iOS の UIPopoverArrowDirection に相当します。ポップオーバーの矢印の位置を指定します。

プロパティ

Camera.Direction

プロパティ

CameraPopoverOptions

iOS 専用のパラメーターです。iPad のライブラリまたはフォトアルバムから、画像を選択するときのポップオーバー ( popover ) の位置とその矢印の方向を指定するときに使用します。画面のオリエンテーション ( および、矢印の表示位置 ) に合うように、ポップオーバーの大きさが修正される場合もあります。「 オリエンテーションは移り変わること 」 を念頭に置いて、矢印の位置を設定することを推奨します。

CameraPopoverHandle

画像選択用のポップオーバーの処理に使用します。

対象プラットフォーム

  • iOS

navigator.camera.getPicture(onSuccess, onFail,
{
    destinationType: Camera.DestinationType.FILE_URI,
    sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
    popoverOptions: new CameraPopoverOptions(300, 300, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY)
});

// Reposition the popover if the orientation changes.
window.onorientationchange = function() {
    var cameraPopoverHandle = new CameraPopoverHandle();
    var cameraPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY);
    cameraPopoverHandle.setPosition(cameraPopoverOptions);
}

camera.getPicture の補足

写真撮影および画像ファイルの保存場所を取得します。

navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
    destinationType: Camera.DestinationType.FILE_URI });

function onSuccess(imageURI) {
    var image = document.getElementById('myImage');
    image.src = imageURI;
}

function onFail(message) {
    alert('Failed because: ' + message);
}

写真の撮影時、および、写真 ( Base64 エンコード形式の画像 ) の取得時に使用します。

/**
 * Warning: Using DATA_URL is not recommended! The DATA_URL destination
 * type is very memory intensive, even with a low quality setting. Using it
 * can result in out of memory errors and application crashes. Use FILE_URI
 * or NATIVE_URI instead.
 */
navigator.camera.getPicture(onSuccess, onFail, { quality: 25,
    destinationType: Camera.DestinationType.DATA_URL
});

function onSuccess(imageData) {
    var image = document.getElementById('myImage');
    image.src = "data:image/jpeg;base64," + imageData;
}

function onFail(message) {
    alert('Failed because: ' + message);
}

Preference ( iOS が対象 )

CameraUsesGeolocation ( 真偽値、デフォルトは、false )。JPEG 形式の画像をキャプチャーする場合、この値を true に設定すると、EXIF ヘッダー内の位置情報を取得できるようになります ( true に設定した場合、位置情報の使用に必要な許可をシステム側にリクエストします )。

<preference name="CameraUsesGeolocation" value="false" />

Android 特有の動作

Android では、インテント ( intent ) を使用し、カメラのアクティビティ ( activity ) を起動させ、画像のキャプチャーを行います。ただし、メモリーの空きが少ない携帯端末では、Cordova 側のアクティビティが強制終了 ( kill ) させられることがあります。このような場合、resume イベントを使用して、強制終了させられたプラグインの情報 ( 実行結果を含む ) を、コールバックに渡します。詳細は、 Cordova 使用時の Android アクティビティのライフサイクルに関する注意点 ( 英語サイト ) をご確認ください。 pendingResult.result には、コールバック側に渡す、保留中の実行結果が入っています ( ここでは URI/URL または エラーメッセージとなります )。また、実行結果が成功か否かを確認する場合、 pendingResult.pluginStatus を使用します。

iOS 特有の動作

コールバック関数の中で、JavaScript の alert() を使用すると、問題が生じる場合があります。この問題を避けるため、alert を setTimeout() 内に記述します。この方法を使用されば、alert が表示される前に、iOS の 画像選択用ダイアログ ( image picker ) または ポップオーバー ( popover ) を、完全に閉じることができます。

setTimeout(function() {
    // do your thing here!
}, 0);

CameraOptions の補足

Android 特有の動作

  • cameraDirection にどんな値を設定しても、背面のカメラを使用した撮影になります。

  • allowEdit の使用時、Android は想定していた動作をしないことがあります。このため、この設定は使用しないでください。 このプラグインを Android へ実装させた場合には、画像のトリミング処理 ( cropping ) は、端末側のアプリを使用して行う仕組みになっています。ただし、プラグイン側では、ユーザーが選択する編集用アプリに関しては、なんら制御ができないため、このプラグインと相性の悪いアプリをユーザーが選択してしまう場合もあり、このような場合、不具合が生じます。もちろん、端末側のアプリとこのプラグインの相性が合うことも場合によってはありますが ( たとえば、Google Photos )、ごくまれなケースです。もし、画像の編集が必須なアプリを開発している場合、画像編集機能を独自に提供している、サードパーティー製のライブラリー・プラグインを使用することも代替案としてご検討ください。

  • Camera.PictureSourceType.PHOTOLIBRARYCamera.PictureSourceType.SAVEDPHOTOALBUM では、どちらの場合でも、同一のフォトアルバムを表示します。

  • quality を 100 に設定、correctOrientation を false に設定、加えて、targetHeight または targetWidth を未設定にした場合、encodingType パラメーターは無視されます。画像の取得先が CAMERA の場合、JPEG ファイル ( システム側のカメラが提供 ) を常に返します。また、PHOTOLIBRARY または SAVEDPHOTOALBUM の場合には、選択されたファイル ( 現状の形式のまま ) が返されます。

iOS 特有の動作

  • destinationType.FILE_URI に設定している場合、写真はアプリの temporary/tmp ディレクトリーに保存されます。なお、このディレクトリーのコンテンツは、アプリが終了したときに削除されます。

  • destinationType.NATIVE_URIsourceType.CAMERA に設定している場合、 saveToPhotoAlbum パラメーターに関わらず、写真は、フォトアルバムに保存されます。

  • destinationType.NATIVE_URIsourceType.PHOTOLIBRARY または sourceType.SAVEDPHOTOALBUM を使用すると、すべての編集オプションは無視され、リンクは元の画像に戻されます。

サンプルコード

カメラ操作プラグインでは、端末搭載のカメラアプリを使用した写真撮影の起動、画像選択用ダイアログの表示と画像の選択などを行えます。次の処理を行うコードのサンプルを、下に示します。

写真の撮影

写真撮影の処理を行う前に、カメラ操作プラグインの getPicture 関数に渡すオプションをいくつか設定します。次のサンプルコード内に推奨のオプションを記述しています。この例では、オプション用に使用するオブジェクトを作成しています。なお、カメラアプリと画像選択用のダイアログの両方をサポートできるように、sourceType は、「 動的 」 に設定することにします。

function setOptions(srcType) {
    var options = {
        // Some common settings are 20, 50, and 100
        quality: 50,
        destinationType: Camera.DestinationType.FILE_URI,
        // In this app, dynamically set the picture source, Camera or photo gallery
        sourceType: srcType,
        encodingType: Camera.EncodingType.JPEG,
        mediaType: Camera.MediaType.PICTURE,
        allowEdit: true,
        correctOrientation: true  //Corrects Android orientation quirks
    }
    return options;
}

メモリーに起因する問題を避けるため、DATA_URL ではなく、FILE_URI を使用します。なお、Android では、エンコード形式として JPEG を推奨します。

写真撮影時、getPicture の第三引数に、オプション用のオブジェクト ( CameraOptions ) を渡します。また、setOptions の呼び出し時に、写真の取得先を指定する Camera.PictureSourceType.CAMERA を渡します。

function openCamera(selection) {

    var srcType = Camera.PictureSourceType.CAMERA;
    var options = setOptions(srcType);
    var func = createNewFileEntry;

    navigator.camera.getPicture(function cameraSuccess(imageUri) {

        displayImage(imageUri);
        // You may choose to copy the picture, save it somewhere, or upload.
        func(imageUri);

    }, function cameraError(error) {
        console.debug("Unable to obtain picture: " + error, "app");

    }, options);
}

写真の撮影後は、写真の表示などを含む、さまざまな処理を行えます。この例では、上述のコードの displayImage 内の処理を記述しています。

function displayImage(imgUri) {

    var elem = document.getElementById('imageFile');
    elem.src = imgUri;
}

いくつかのプラットフォームでは、画像を表示する場合、Content-Security-Policy<meta> 要素に、URI を設定する必要があります。以下は、例になります。

<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: ms-appdata: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">

写真の撮影とサムネイル ( 縮小した写真 ) の取得

縮小された画像を取得したい場合には、CameraOptions オブジェクトの targetWidthtargetHeight に、希望するサイズの値を入れて渡します。ここでは、100 x 100px のボックスに収まる画像が返ってくるように設定します ( アスペクト比は保持されるので、ソースの縦または横のどちらか大きい方に 100px が適用されます。 )。

function openCamera(selection) {

    var srcType = Camera.PictureSourceType.CAMERA;
    var options = setOptions(srcType);
    var func = createNewFileEntry;

    if (selection == "camera-thmb") {
        options.targetHeight = 100;
        options.targetWidth = 100;
    }

    navigator.camera.getPicture(function cameraSuccess(imageUri) {

        // Do something

    }, function cameraError(error) {
        console.debug("Unable to obtain picture: " + error, "app");

    }, options);
}

写真のライブラリーからファイルを選択

画像選択用のダイアログからファイルを選択する場合、CameraOptions オブジェクトを使用して、ダイアログを表示するよう設定します ( sourceTypeCamera.PictureSourceType.SAVEDPHOTOALBUM に設定します )。実際にダイアログを表示させるときには、左記のオプションを指定したオブジェクトを使用して、getPicture を呼び出します。

function openFilePicker(selection) {

    var srcType = Camera.PictureSourceType.SAVEDPHOTOALBUM;
    var options = setOptions(srcType);
    var func = createNewFileEntry;

    navigator.camera.getPicture(function cameraSuccess(imageUri) {

        // Do something

    }, function cameraError(error) {
        console.debug("Unable to obtain picture: " + error, "app");

    }, options);
}

画像の選択とサムネイル ( 縮小した写真 ) の取得

画像選択用のダイアログで選択したファイルを縮小する場合には、上述の方法と同じように、targetHeighttargetWidth を適宜設定します。

function openFilePicker(selection) {

    var srcType = Camera.PictureSourceType.SAVEDPHOTOALBUM;
    var options = setOptions(srcType);
    var func = createNewFileEntry;

    if (selection == "picker-thmb") {
        // To downscale a selected image,
        // Camera.EncodingType (e.g., JPEG) must match the selected image type.
        options.targetHeight = 100;
        options.targetWidth = 100;
    }

    navigator.camera.getPicture(function cameraSuccess(imageUri) {

        // Do something with image

    }, function cameraError(error) {
        console.debug("Unable to obtain picture: " + error, "app");

    }, options);
}

写真の撮影と FileEntry オブジェクトの取得

別の場所への画像のコピー、画像のアップロード ( ファイル転送プラグイン/FileTransfer プラグイン の使用 ) などを行う場合、カメラアプリから返された写真に紐づけされている FileEntry オブジェクトを使用します。オブジェクトを取得する場合には、カメラアプリが返す file URI を使用して、 window.resolveLocalFileSystemURL を呼び出します ( CameraOptions オブジェクト内で、 destinationTypeCamera.DestinationType.FILE_URI に設定する必要があります。通常、デフォルトで、この設定になっています )。

window.resolveLocalFileSystemURL を呼ぶためには、 ファイル操作プラグイン ( File プラグイン ) が必要です。

window.resolveLocalFileSystemURL の実行例を次に記します。この関数で使用している image URI は、getPicture の成功時のコールバックから渡されたものです。resolveLocalFileSystemURL の成功時のハンドラーに FileEntry オブジェクトが渡されます。

function getFileEntry(imgUri) {
    window.resolveLocalFileSystemURL(imgUri, function success(fileEntry) {

        // Do something with the FileEntry object, like write to it, upload it, etc.
        // writeFile(fileEntry, imgUri);
        console.log("got file: " + fileEntry.fullPath);
        // displayFileData(fileEntry.nativeURL, "Native URL");

    }, function () {
      // If don't get the FileEntry (which may happen when testing
      // on some emulators), copy to a new FileEntry.
        createNewFileEntry(imgUri);
    });
}

上記の例では、有効な FileEntry オブジェクトを取得できなかった場合、アプリ側の createNewFileEntry を呼び出しています。カメラアプリが返した image URL を使用すれば、有効な FileEntry を取得できるはずですが、エミュレーターによっては、プラットフォームの動作が異なり、画像選択用のダイアログが返すファイル情報も異なってきます。

FileEntry への書き込み方法は、ファイル操作プラグインの README をご確認ください。

次のコードでは、アプリのキャッシュ用ディレクトリー ( サンドボックス内のストレージ ) 内に、 tempFile.jpeg と名付けたファイルを作成しています。新たな FileEntry オブジェクトを使用すれば、さまざまな処理 ( 画像のコピー、アップデートなど ) を行えます。

function createNewFileEntry(imgUri) {
    window.resolveLocalFileSystemURL(cordova.file.cacheDirectory, function success(dirEntry) {

        // JPEG file
        dirEntry.getFile("tempFile.jpeg", { create: true, exclusive: false }, function (fileEntry) {

            // Do something with it, like write to it, upload it, etc.
            // writeFile(fileEntry, imgUri);
            console.log("got file: " + fileEntry.fullPath);
            // displayFileData(fileEntry.fullPath, "File copied to");

        }, onErrorCreateFile);

    }, onErrorResolveUrl);
}

関連項目:

最終更新