How to use Camera Preview plugin in Ionic with Capacitor v3

Written by Kasim Ridwan on May 4th, 2022 Views Report Post

In this article, we will be looking at how to make use of the Camera Preview Plugin in our ionic apps. This plugin doesn't cause your app to restart whenever the camera is launched unlike the Camera Plugin. Research shows that the issue will occur when the device running the app is on low memory.

Before we get started, make sure you have your development environment set up for ionic else follow the official documentation Let's start by creating a blank ionic project:

ionic start camera-preview blank

Select Angular from the options and wait for some minutes while the project is created.

Navigate to the project directory by running the command below:

cd camera-preview

We can now install our camera preview plugin with this command:

npm install @capacitor-community/camera-preview

Then build the project and synchronise the changes by running the command below:

ionic build && npx cap sync

Launch the app by running the command below. This will open the project in your browser.

ionic serve

Open the newly created project in your favourite code editor. Also, we need to generate one more page component to render our camera.

ionic generate page preview

In our project directory, we will now have a folder for home & another for preview. So let's open the home.page.html and add a button to launch the camera.

<ion-header [translucent]="true">
  <ion-toolbar>
    <ion-title>
      Camera Preview Demo
    </ion-title>
  </ion-toolbar>
</ion-header>

<ion-content [fullscreen]="true">
    <div *ngIf="image">
        <img [src]="image" alt="" srcset="">
    </div>
    <ion-button (click)="openCamera()" color="primary" expand="block" fill="solid" size="default">
       Open Camera
    </ion-button>
</ion-content>

The next thing to do is to register the preview module in our app.module.ts file. Your app.module.ts should look like below:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';

import { IonicModule, IonicRouteStrategy } from '@ionic/angular';

import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { PreviewPageModule } from "./preview/preview.module";

@NgModule({
  declarations: [AppComponent],
  entryComponents: [],
  imports: [
    BrowserModule,
    IonicModule.forRoot(),
    AppRoutingModule,
    PreviewPageModule
  ],
  providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }],
  bootstrap: [AppComponent],
})
export class AppModule { }

Let's open the home.page.ts file and add the code for the openCamera() method.

Import the ionic modal and the preview page.

import { ModalController } from '@ionic/angular';
import { PreviewPage } from '../preview/preview.page';

Then inject the modal into the constructor.

constructor(private modal: ModalController) {}

All is set and we can now implement the function to launch our camera in the preview modal.

async openCamera() {
    const modal = await this.modal.create({
        component: PreviewPage,
        cssClass: '',
        animated: true
    });
    return await modal.present();
}

Let's implement the look and feel of the camera by opening our preview.page.html and the code below:

<ion-content id="content" [fullscreen]="true">
  <div *ngIf="cameraActive">
      <ion-button (click)="stopCamera()" expand="block" id="close">
          <ion-icon slot="icon-only" name="close-circle"></ion-icon>
      </ion-button>

      <ion-button (click)="takePicture()" expand="block" id="capture">
          <ion-icon slot="icon-only" name="camera"></ion-icon>
      </ion-button>

      <ion-button (click)="flipCamera()" expand="block" id="flip">
          <ion-icon slot="icon-only" name="repeat"></ion-icon>
      </ion-button>
  </div>
</ion-content>

The next thing is to add some styling to our buttons. Open preview.page.scss file and the code below:

ion-content {
  --background: transparent !important;
}

#capture {
  position: absolute;
  bottom: 30px;
  left: calc(50% - 25px);
  width: 50px;
  height: 50px;
  z-index: 99999;
}

#flip {
  position: absolute;
  bottom: 30px;
  left: calc(50% + 125px);
  width: 50px;
  height: 50px;
  z-index: 99999;
}

#close {
  position: absolute;
  bottom: 30px;
  left: calc(50% - 175px);
  width: 50px;
  height: 50px;
  z-index: 99999;
}

#capture::part(native) {
  border-radius: 30px;
}

#close::part(native) {
  border-radius: 30px;
}

#flip::part(native) {
  border-radius: 30px;
}

Let's open the preview.page.ts file and add it to our imports.

import { CameraPreview } from '@capacitor/core';
import { CameraPreviewOptions, CameraPreviewPictureOptions } from '@capacitor-community/camera-preview';
import '@capacitor-community/camera-preview';
import { ModalController } from '@ionic/angular';

Then inject the modal into the constructor. Also, we will declare two variables.

image = null;
cameraActive = false;
constructor(private modal: ModalController) {}

Since we are using a modal, we need to launch the camera on the device whenever the Open Camera button is clicked. Let's create a function called launchCamera() and call it inside ngOnInit()

ngOnInit() {
   this.launchCamera()
}

launchCamera() {
    const cameraPreviewOptions: CameraPreviewOptions = {
      position: 'front', // front or rear
      parent: 'content', // the id on the ion-content
      className: '',
      width: window.screen.width, //width of the camera display
      height: window.screen.height - 200, //height of the camera
      toBack: false,
    };
    CameraPreview.start(cameraPreviewOptions);
    this.cameraActive = true;
}

Let's create a function to take our picture. Once the picture is taken, we need to stop the camera and close the modal. The result is a base64 string which we will pass back when the modal is dismissed.

async takePicture() {
    const cameraPreviewPictureOptions: CameraPreviewPictureOptions = {
      quality: 90
    };
    const result = await CameraPreview.capture(cameraPreviewPictureOptions);
    this.image = `data:image/jpeg;base64,${result.value}`;
    this.stopCamera();
}

We need to add the function to stop the camera and close the modal.

async stopCamera() {
    await CameraPreview.stop();
    this.modal.dismiss(this.image);
}

We also need to add the function to switch the camera from front to back and vice versa.

Note: this won't work if you test it in a browser.

async flipCamera() {
   await CameraPreview.flip();
}

Let's open our home.page.ts file to listen to the modal close event. To do that we need to update the openCamera() function.

 modal.onDidDismiss().then((data) => {
     if (data !== null) {
        this.image = data.data;
     }
 });

Voila!!! Let's test it in the browser. You can find the full code here:

Sample-one sample-two

Comments (0)