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:
| Option | What it controls |
|---|---|
| quality | A 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 |
| destinationType | Camera.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 |
| sourceType | Camera.PictureSourceType.CAMERA opens the live camera; Camera.PictureSourceType.PHOTOLIBRARY opens the device's existing photo gallery instead |
| encodingType | Camera.EncodingType.JPEG (the default) or Camera.EncodingType.PNG, controlling the image format returned |
| targetWidth / targetHeight | Resizes 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)
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.