I’ve been working on an Ionic project that involves using the Capacitor Camera Preview plugin to take selfies. Everything works fine when I run the app in the browser or on an emulator. However, when I build the APK and run it on a physical device, the camera preview shows a white screen. The overlay elements are visible, but the camera feed is not displayed.
I’ve ensured that the CameraPreviewOptions are correctly set, and I’ve tried adjusting the z-index and background styles as suggested in various forums, but the issue persists. Here are the details of my setup:
Relevant Code Snippets
TypeScript (bp-tirar-selfie.component.ts):
import { Component, OnInit } from '@angular/core';
import { CameraPreview, CameraPreviewOptions } from '@capacitor-community/camera-preview';
import { SharedModule } from '../../shared.module';
import { InstrucoesSelfieComponent } from './modal-instrucoes-selfie/instrucoes-selfie.component';
import { ModalController, NavController } from '@ionic/angular';
import { VisualizarFotoComponent } from './modal-visualizar-foto/visualizar-foto.component';
import { OverlayService } from 'src/app/core/services/overlay/overlay.service';
const cameraPreviewOptions: CameraPreviewOptions = {
position: 'front',
className: 'cameraPreview',
parent: 'cameraPreview', // Ensure this element exists in your template
toBack: true, // Push the camera preview behind the web view content
};
@Component({
selector: 'app-bp-tirar-selfie',
templateUrl: './bp-tirar-selfie.component.html',
styleUrls: ['./bp-tirar-selfie.component.scss'],
standalone: true,
imports: [SharedModule],
})
export class BpTirarSelfieComponent implements OnInit {
public cameraActive = false;
public image: string | null = null;
public selfieUsuario = '';
constructor(private modalCtrl: ModalController, private overlayService: OverlayService) { }
ngOnInit() {
this.mostrarInstrucoes();
}
public async mostrarInstrucoes() {
const modal = await this.modalCtrl.create({
component: InstrucoesSelfieComponent,
backdropDismiss: false,
});
modal.onDidDismiss().then(() => {
this.openCamera();
});
return await modal.present();
}
public openCamera() {
CameraPreview.start(cameraPreviewOptions);
this.cameraActive = true;
}
public async takePicture() {
try {
const result = await CameraPreview.capture();
const base64PictureData = result.value;
sessionStorage.setItem('fotoFace', base64PictureData);
this.stopCamera();
await this.verificarFoto(base64PictureData);
} catch (error) {
console.error(error);
this.overlayService.toast({
message: 'Erro ao tirar foto, por favor tente novamente.',
duration: 2000,
color: 'danger',
});
}
}
public async verificarFoto(foto: string) {
const modal = await this.modalCtrl.create({
component: VisualizarFotoComponent,
componentProps: {
foto: 'data:image/png;base64,' + foto,
},
});
modal.onDidDismiss().then((ret) => {
if (ret.data && ret.data === 'mudar') {
sessionStorage.removeItem('fotoFace');
this.openCamera();
} else {
this.returnPage();
}
});
return await modal.present();
}
public async returnPage() {
await this.stopCamera();
this.modalCtrl.dismiss();
}
public async switchCamera() {
CameraPreview.flip();
}
public async stopCamera() {
CameraPreview.stop();
}
}
HTML (bp-tirar-selfie.component.html):
<ion-content>
<div id="cameraPreview" class="cameraPreview">
<!-- Camera feed will be displayed here -->
</div>
<img class="molde-cabeca" src="/assets/images/perfil/face.png" *ngIf="cameraActive" />
<p class="texto" *ngIf="cameraActive">
Enquadre seu rosto na moldura e aperte o botão Amarelo para tirar uma nova
foto. Tire máscaras, óculos e outros adereços.
</p>
<div *ngIf="cameraActive">
<ion-fab vertical="bottom" horizontal="start">
<ion-fab-button color="light" (click)="returnPage()" routerDirection="back">
<ion-icon name="arrow-back"></ion-icon>
</ion-fab-button>
</ion-fab>
<ion-fab vertical="bottom" horizontal="center">
<ion-fab-button color="warning" (click)="takePicture()">
<ion-icon name="camera"></ion-icon>
</ion-fab-button>
</ion-fab>
<ion-fab vertical="bottom" horizontal="end">
<ion-fab-button color="light" (click)="switchCamera()">
<ion-icon name="camera-reverse-sharp"></ion-icon>
</ion-fab-button>
</ion-fab>
</div>
</ion-content>
CSS (bp-tirar-selfie.component.scss):
.cameraPreview {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1; /* Ensure it's behind other elements */
background: transparent;
}
ion-content {
--background: transparent; /* Make sure the background is transparent */
position: relative; /* Ensure the content positions correctly */
z-index: 0; /* Default z-index for content */
}
.molde-cabeca {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 1; /* Ensure the frame is above the camera preview */
}
Problem Description
- When running the app on a device using the APK, the camera preview area shows a white screen.
- The overlay elements (e.g., the frame image) are visible and interactable.
- The camera feed is not displayed, though the camera appears to function as expected (e.g., taking pictures works).