Cordova Camera Plugin

The Camera plugin is usually the first native-device plugin developers reach for, because capturing or selecting a photo is such a common feature — profile pictures, receipt scanning, product photos, and more. This page covers cordova-plugin-camera in depth: how to install it, every option worth knowing on navigator.camera.getPicture(), two full worked examples (capture and library-pick), and the error handling you should always include.

Installing the Plugin

Add the plugin from your project root, exactly like any other Cordova plugin:

cordova plugin add cordova-plugin-camera

Once installed, a global navigator.camera object becomes available in your JavaScript after deviceready fires, as covered in the previous two lessons.

The getPicture() API

The entire plugin centers on a single method: navigator.camera.getPicture(successCallback, errorCallback, options). It's asynchronous — it opens the native camera UI (or photo picker), waits for the user to take or choose a photo (or cancel), and then calls back into your JavaScript with the result.

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

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

function onFail(message) {
    console.log('Failed because: ' + message);
}

Key Options Reference

The third argument to getPicture() is an options object. You rarely need every option at once, but these are the ones you'll reach for most:

OptionWhat it controls
qualityA number from 0-100 controlling JPEG compression quality. Lower values mean a smaller file, which matters a lot when you plan to upload the photo over a mobile connection
destinationTypeCamera.DestinationType.DATA_URL returns the image as a base64-encoded string (easy to drop straight into an <img> tag); Camera.DestinationType.FILE_URI returns a file path instead, better when you plan to upload the file directly or store it on disk
sourceTypeCamera.PictureSourceType.CAMERA opens the live camera; Camera.PictureSourceType.PHOTOLIBRARY opens the device's existing photo gallery instead
encodingTypeCamera.EncodingType.JPEG (the default) or Camera.EncodingType.PNG, controlling the image format returned
targetWidth / targetHeightResizes the image to fit within these pixel dimensions before it's returned — useful to avoid handling a full-resolution multi-megapixel photo when you only need a thumbnail

Full Example: Capture a Photo and Display It

This example takes a photo with the live camera, requests it as a base64 DATA_URL so it can be dropped straight into an <img> tag, and resizes it down to a reasonable size first:

document.addEventListener('deviceready', onDeviceReady, false);

function onDeviceReady() {
    document.getElementById('takePhotoBtn').onclick = capturePhoto;
}

function capturePhoto() {
    navigator.camera.getPicture(onCaptureSuccess, onCaptureError, {
        quality: 60,
        destinationType: Camera.DestinationType.DATA_URL,
        sourceType: Camera.PictureSourceType.CAMERA,
        encodingType: Camera.EncodingType.JPEG,
        targetWidth: 800,
        targetHeight: 800
    });
}

function onCaptureSuccess(imageData) {
    var img = document.getElementById('previewImage');
    img.src = 'data:image/jpeg;base64,' + imageData;
    img.style.display = 'block';
}

function onCaptureError(message) {
    console.log('Camera capture failed: ' + message);
    alert('Could not take photo. ' + message);
}

Matching HTML for the button and preview image referenced above:

<button id="takePhotoBtn">Take Photo</button>
<img id="previewImage" style="display:none; max-width:100%;" />

Full Example: Pick a Photo from the Library

Sometimes the user already has the photo they want on their device and doesn't need to take a new one. Setting sourceType to PHOTOLIBRARY opens the device's photo gallery picker instead of the live camera — everything else about the call stays the same:

function pickFromLibrary() {
    navigator.camera.getPicture(onCaptureSuccess, onCaptureError, {
        quality: 60,
        destinationType: Camera.DestinationType.DATA_URL,
        sourceType: Camera.PictureSourceType.PHOTOLIBRARY
    });
}

document.getElementById('pickPhotoBtn').onclick = pickFromLibrary;

Because both functions above share the same onCaptureSuccess and onCaptureError handlers, one pair of buttons can offer users a choice between taking a fresh photo and reusing one they already have, without duplicating any display logic.

Always Handle the Error Callback

It's tempting to only wire up the success path during development, but the error callback is not optional in a real app. getPicture() calls it whenever:

  • The user taps Cancel instead of taking or choosing a photo — this is a completely normal, expected user action, not a crash
  • Camera or photo library permission was denied by the user (see the permissions note below)
  • The device has no camera hardware available (rare, but possible on some tablets or emulators)
Don't treat cancellation as a bug: your onFail callback will fire in the completely normal case where the user simply changes their mind. Show a neutral message or silently do nothing — don't show an alarming "Error!" dialog for a plain cancel.

Runtime Permissions on Android

Since Android 6.0 (API level 23), camera and storage access are runtime permissions — declaring them in config.xml is not enough on its own. The first time your app calls getPicture(), Android shows the user a system permission dialog, and the user must explicitly tap Allow. If they tap Deny, your error callback fires just as it would for a cancellation, so your error handling above already covers this case gracefully. iOS has an equivalent one-time permission prompt for camera and photo library access.

Up next: Continue to the Geolocation Plugin to read and watch the device's GPS position.