We’re going to use Capacitor to access native functionality from our Ionic applications.

If you don’t have your Ionic app set up yet, you can quickly create a new one with the ionic start command, with that in mind, let’s get started.

Let’s start with understanding a bit more about capacitor and its role in mobile development. The easiest way to “get it” is by seeing it as a replacement for Cordova.

Capacitor allows you to wrap your app into a native container and helps you communicate with the phone’s native capabilities. You can use it to create a native build of your application (iOS and Android).

Enabling Capacitor

To set up Capacitor, we can take advantage of the Ionic CLI, it provides a handy command we can use, so, let’s open the terminal on the root of our application and type:

ionic integrations enable capacitor

It will install all the needed capacitor packages, and it will create the configuration file in the root of your project called capacitor.config.ts.

If you open it, you’ll find something like this:

import { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  appId: 'io.ionic.starter',
  appName: 'app-name',
  webDir: 'www',
  bundledWebRuntime: false,
};

export default config;

Where you’ll focus on 2 things, first, make sure that webDir matches the build folder of your application, where it generates the builds, you can check this in the angular.json file if you’re using Angular.

And the second thing, is to change the appId to something that matches more your brand, instead of Ionic’s default ID.

Before doing anything else, it is a good idea to create a build of our application, since this creates the web assets directory that capacitor copies into the native projects.

ionic build

That command will generate a build of our application inside the www/ folder, which is the folder Capacitor is watching.

> SIDE-NOTE: That command generates a development build. If you want to create a production build for your application, add the --prod flag.

Now we can add our platforms. You can add either iOS or Android by using the commands:

ionic capacitor add ios
ionic capacitor add android

Remember that you need XCode installed on a Mac to build for iOS.

To test that everything is working, we’ll use the command:

ionic capacitor run android

It will ask you what device you want to use, depending if you’re using multiple emulators or have a physical device connected to your computer.

Once you choose the device, it will open it, and open our application there.

Using the Camera API

Now capacitor is ready to use, and we’ll, and we’ll start by connecting the camera API.

For using the camera API the first thing we need is to install the camera package, you do that by opening the terminal and typing:

npm install @capacitor/camera

Once the camera package is installed, you can go into whatever page you’re going to use the camera, and import these 2 packages:

import { Camera, CameraResultType } from '@capacitor/camera';

Then you can create a function that takes the picture:

async takePicture() {}

It’s going to be an async function, since the Camera function returns a promise. Inside, we’ll use the Camera to take the picture, and for that we’ll use the Camera.getPhoto({}) function:

async takePicture() {
  const image = await Camera.getPhoto({});
}

The getPhoto({}) function takes multiple parameters, you can check them all in the official Capacitor documentation, but the most important ones for us right now are the following:

  • quality, which takes a number up to 100 to indicate the picture’s quality resolution.
  • allowEditing, which takes a boolean, and indicates if the user will be able to edit the picture after taking it.
  • resultType, is perhaps the most important one, because it tells the app which format we’re sending back for the picture, it accepts 3 values: ‘Base64’, DataUrl, Uri.

So in the end our function would look like this:

async takePicture() {
  const image = await Camera.getPhoto({
    quality: 100,
    allowEditing: false,
    resultType: CameraResultType.DataUrl,
  });

  // Here you get the image as result.
  const theActualPicture = image.dataUrl;
}

Make sure you test all of this is working, by running:

ionic capacitor run android

It should open your application and the camera functionality should be good to go.

Permissions Camera Needs

For deploying to Google Play or the App Store, you’ll need to properly declare the permissions the app needs, in the case of the Camera, you’ll need to do this for the platforms you want to deploy to, for example, for Android, you need to add:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

To the permissions section of the android/app/src/main/AndroidManifest.xml file.

And for iOS, you’ll need to edit the Info.plist, and add the following descriptions: NSCameraUsageDescription, NSPhotoLibraryAddUsageDescription, NSPhotoLibraryUsageDescription.

Those are the ones that show up in the permission pop up to let the user how you’ll use the camera or gallery.

Making it work in the web

Some Capacitor plugins, such as Camera, have web platform support, which lets Capacitor use a web implementation so that your code works as-is on Android, iOS, and the Web.

To enable this, the Ionic team created a package called pwa-elements, to install it, let’s open our terminal, in the root of our application and type:

npm install @ionic/pwa-elements

And then go into the src/main.ts file and define the custom elements:

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

// Here you import it
import { defineCustomElements } from '@ionic/pwa-elements/loader';

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic()
  .bootstrapModule(AppModule)
  .catch(err => console.log(err));

// Call the element loader after the platform has been bootstrapped
defineCustomElements(window);

And that is it. Now you have a fully functional way of capturing photos with your camera.

Do let me know in the comments if there are any questions 😃