Skip to content

Cap-go/capacitor-camera-preview

Repository files navigation

Capacitor Camera Preview Plugin

Capgo - Instant updates for capacitor

NPM Version NPM Downloads GitHub Repo stars GitHub Actions Workflow Status GitHub License Maintenance

Capacitor plugin that allows camera interaction from Javascript and HTML
(based on cordova-plugin-camera-preview).


This plugin is compatible Capacitor 7 and above.

Use v6 for Capacitor 6 and below.

PR's are greatly appreciated.

-- @riderx, current maintainers

Remember to add the style below on your app's HTML or body element:

:root {
  --ion-background-color: transparent !important;
}

Take into account that this will make transparent all ion-content on application, if you want to show camera preview only in one page, just add a custom class to your ion-content and make it transparent:

.my-custom-camera-preview-content {
  --background: transparent;
}

If the camera preview is not displaying after applying the above styles, apply transparent background color to the root div element of the parent component Ex: VueJS >> App.vue component

<template>
  <ion-app id="app">
    <ion-router-outlet />
  </ion-app>
</template>

<style>
#app {
  background-color: transparent !important;
}
<style>

If it don't work in dark mode here is issue who explain how to fix it: capacitor-community/camera-preview#199

Good to know

Video and photo taken with the plugin are never removed, so do not forget to remove them after used to not bloat the user phone.

use https://capacitorjs.com/docs/apis/filesystem#deletefile for that

Fast base64 from file path (no bridge)

When using storeToFile: true, you can avoid sending large base64 strings over the Capacitor bridge:

import { CameraPreview, getBase64FromFilePath } from '@capgo/camera-preview'

await CameraPreview.start({ storeToFile: true });
// Take a picture and get a file path
const { value: filePath } = await CameraPreview.capture({ quality: 85 })

// Convert the file to base64 entirely on the JS side (fast, no bridge)
const base64 = await getBase64FromFilePath(filePath)

// Optionally cleanup the temp file natively
await CameraPreview.deleteFile({ path: filePath })

Exposure controls (iOS & Android)

This plugin exposes camera exposure controls on iOS and Android:

  • Exposure modes: "AUTO" | "LOCK" | "CONTINUOUS" | "CUSTOM"
  • Exposure compensation (EV bias): get range { min, max, step }, read current value, and set new value

Platform notes:

  • iOS: The camera starts in CONTINUOUS by default. Switching to AUTO or CONTINUOUS resets EV to 0. The step value is approximated to 0.1 since iOS does not expose the bias step.
  • Android: AE lock/unlock and mode are handled via CameraX + Camera2 interop. The step value comes from CameraX ExposureState and may vary per device.

Example (TypeScript):

import { CameraPreview } from '@capgo/camera-preview';

// Query supported modes
const { modes } = await CameraPreview.getExposureModes();
console.log('Supported exposure modes:', modes);

// Get current mode
const { mode } = await CameraPreview.getExposureMode();
console.log('Current exposure mode:', mode);

// Set mode (AUTO | LOCK | CONTINUOUS | CUSTOM)
await CameraPreview.setExposureMode({ mode: 'CONTINUOUS' });

// Get EV range (with step)
const { min, max, step } = await CameraPreview.getExposureCompensationRange();
console.log('EV range:', { min, max, step });

// Read current EV
const { value: currentEV } = await CameraPreview.getExposureCompensation();
console.log('Current EV:', currentEV);

// Increment EV by one step and clamp to range
const nextEV = Math.max(min, Math.min(max, currentEV + step));
await CameraPreview.setExposureCompensation({ value: nextEV });

Example app (Ionic):

  • Exposure mode toggle (sun icon) cycles through modes.
  • EV controls (+/−) are placed in a top‑right floating action bar, outside the preview area.

Installation

yarn add @capgo/camera-preview

or

npm install @capgo/camera-preview

Then run

npx cap sync

Optional Configuration

To use certain features of this plugin, you will need to add the following permissions/keys to your native project configurations.

Android

In your android/app/src/main/AndroidManifest.xml:

  • Audio Recording (disableAudio: false):

    <uses-permission android:name="android.permission.RECORD_AUDIO" />
  • Saving to Gallery (saveToGallery: true):

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  • Location in EXIF Data (withExifLocation: true):

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

iOS

In your ios/App/App/Info.plist, you must provide descriptions for the permissions your app requires. The keys are added automatically, but you need to provide the string values.

  • Audio Recording (disableAudio: false):

    <key>NSMicrophoneUsageDescription</key>
    <string>To record audio with videos</string>
  • Saving to Gallery (saveToGallery: true):

    <key>NSPhotoLibraryUsageDescription</key>
    <string>To save photos to your gallery</string>
  • Location in EXIF Data (withExifLocation: true):

    <key>NSLocationWhenInUseUsageDescription</key>
    <string>To add location data to your photos</string>

Extra Android installation steps

Important camera-preview 3+ requires Gradle 7. Open android/app/src/main/AndroidManifest.xml and above the closing </manifest> tag add this line to request the CAMERA permission:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

For more help consult the Capacitor docs.

Extra iOS installation steps

You will need to add two permissions to Info.plist. Follow the Capacitor docs and add permissions with the raw keys NSCameraUsageDescription and NSMicrophoneUsageDescription. NSMicrophoneUsageDescription is only required, if audio will be used. Otherwise set the disableAudio option to true, which also disables the microphone permission request.

Extra Web installation steps

Add import '@capgo/camera-preview' to you entry script in ionic on app.module.ts, so capacitor can register the web platform from the plugin

Exemple with Capacitor uploader:

Documentation for the uploader

  import { CameraPreview } from '@capgo/camera-preview'
  import { Uploader } from '@capgo/capacitor-uploader';


  async function record() {
    await CameraPreview.startRecordVideo({ storeToFile: true })
    await new Promise(resolve => setTimeout(resolve, 5000))
    const fileUrl = await CameraPreview.stopRecordVideo()
    console.log(fileUrl.videoFilePath)
    await uploadVideo(fileUrl.videoFilePath)
  }

  async function uploadVideo(filePath: string) {
    Uploader.addListener('events', (event) => {
      switch (event.name) {
        case 'uploading':
          console.log(`Upload progress: ${event.payload.percent}%`);
          break;
        case 'completed':
          console.log('Upload completed successfully');
          console.log('Server response status code:', event.payload.statusCode);
          break;
        case 'failed':
          console.error('Upload failed:', event.payload.error);
          break;
      }
    });
    try {
      const result = await Uploader.startUpload({
        filePath,
        serverUrl: 'S#_PRESIGNED_URL',
        method: 'PUT',
        headers: {
          'Content-Type': 'video/mp4',
        },
        mimeType: 'video/mp4',
      });
      console.log('Video uploaded successfully:', result.id);
    } catch (error) {
      console.error('Error uploading video:', error);
      throw error;
    }
  }

API

The main interface for the CameraPreview plugin.

start(...)

start(options: CameraPreviewOptions) => Promise<{ width: number; height: number; x: number; y: number; }>

Starts the camera preview.

Param Type Description
options CameraPreviewOptions - The configuration for the camera preview.

Returns: Promise<{ width: number; height: number; x: number; y: number; }>

Since: 0.0.1


stop()

stop() => Promise<void>

Stops the camera preview.

Since: 0.0.1


capture(...)

capture(options: CameraPreviewPictureOptions) => Promise<{ value: string; exif: ExifData; }>

Captures a picture from the camera.

If storeToFile was set to true when starting the preview, the returned value will be an absolute file path on the device instead of a base64 string. Use getBase64FromFilePath to get the base64 string from the file path.

Param Type Description
options CameraPreviewPictureOptions - The options for capturing the picture.

Returns: Promise<{ value: string; exif: ExifData; }>

Since: 0.0.1


captureSample(...)

captureSample(options: CameraSampleOptions) => Promise<{ value: string; }>

Captures a single frame from the camera preview stream.

Param Type Description
options CameraSampleOptions - The options for capturing the sample.

Returns: Promise<{ value: string; }>

Since: 0.0.1


getSupportedFlashModes()

getSupportedFlashModes() => Promise<{ result: CameraPreviewFlashMode[]; }>

Gets the flash modes supported by the active camera.

Returns: Promise<{ result: CameraPreviewFlashMode[]; }>

Since: 0.0.1


setAspectRatio(...)

setAspectRatio(options: { aspectRatio: "4:3" | "16:9"; x?: number; y?: number; }) => Promise<{ width: number; height: number; x: number; y: number; }>

Set the aspect ratio of the camera preview.

Param Type Description
options { aspectRatio: '4:3' | '16:9'; x?: number; y?: number; } - The desired aspect ratio and optional position. - aspectRatio: The desired aspect ratio ('4:3' or '16:9') - x: Optional x coordinate for positioning. If not provided, view will be auto-centered horizontally. - y: Optional y coordinate for positioning. If not provided, view will be auto-centered vertically.

Returns: Promise<{ width: number; height: number; x: number; y: number; }>

Since: 7.5.0


getAspectRatio()

getAspectRatio() => Promise<{ aspectRatio: "4:3" | "16:9"; }>

Gets the current aspect ratio of the camera preview.

Returns: Promise<{ aspectRatio: '4:3' | '16:9'; }>

Since: 7.5.0


setGridMode(...)

setGridMode(options: { gridMode: GridMode; }) => Promise<void>

Sets the grid mode of the camera preview overlay.

Param Type Description
options { gridMode: GridMode; } - The desired grid mode ('none', '3x3', or '4x4').

Since: 8.0.0


getGridMode()

getGridMode() => Promise<{ gridMode: GridMode; }>

Gets the current grid mode of the camera preview overlay.

Returns: Promise<{ gridMode: GridMode; }>

Since: 8.0.0


getHorizontalFov()

getHorizontalFov() => Promise<{ result: number; }>

Gets the horizontal field of view (FoV) for the active camera. Note: This can be an estimate on some devices.

Returns: Promise<{ result: number; }>

Since: 0.0.1


getSupportedPictureSizes()

getSupportedPictureSizes() => Promise<{ supportedPictureSizes: SupportedPictureSizes[]; }>

Gets the supported picture sizes for all cameras.

Returns: Promise<{ supportedPictureSizes: SupportedPictureSizes[]; }>

Since: 7.4.0


setFlashMode(...)

setFlashMode(options: { flashMode: CameraPreviewFlashMode | string; }) => Promise<void>

Sets the flash mode for the active camera.

Param Type Description
options { flashMode: string; } - The desired flash mode.

Since: 0.0.1


flip()

flip() => Promise<void>

Toggles between the front and rear cameras.

Since: 0.0.1


setOpacity(...)

setOpacity(options: CameraOpacityOptions) => Promise<void>

Sets the opacity of the camera preview.

Param Type Description
options CameraOpacityOptions - The opacity options.

Since: 0.0.1


stopRecordVideo()

stopRecordVideo() => Promise<{ videoFilePath: string; }>

Stops an ongoing video recording.

Returns: Promise<{ videoFilePath: string; }>

Since: 0.0.1


startRecordVideo(...)

startRecordVideo(options: CameraPreviewOptions) => Promise<void>

Starts recording a video.

Param Type Description
options CameraPreviewOptions - The options for video recording. Only iOS.

Since: 0.0.1


isRunning()

isRunning() => Promise<{ isRunning: boolean; }>

Checks if the camera preview is currently running.

Returns: Promise<{ isRunning: boolean; }>

Since: 7.5.0


getAvailableDevices()

getAvailableDevices() => Promise<{ devices: CameraDevice[]; }>

Gets all available camera devices.

Returns: Promise<{ devices: CameraDevice[]; }>

Since: 7.5.0


getZoom()

getZoom() => Promise<{ min: number; max: number; current: number; lens: LensInfo; }>

Gets the current zoom state, including min/max and current lens info.

Returns: Promise<{ min: number; max: number; current: number; lens: LensInfo; }>

Since: 7.5.0


getZoomButtonValues()

getZoomButtonValues() => Promise<{ values: number[]; }>

Returns zoom button values for quick switching.

  • iOS/Android: includes 0.5 if ultra-wide available; 1 and 2 if wide available; 3 if telephoto available
  • Web: unsupported

Returns: Promise<{ values: number[]; }>

Since: 7.5.0


setZoom(...)

setZoom(options: { level: number; ramp?: boolean; autoFocus?: boolean; }) => Promise<void>

Sets the zoom level of the camera.

Param Type Description
options { level: number; ramp?: boolean; autoFocus?: boolean; } - The desired zoom level. ramp is currently unused. autoFocus defaults to true.

Since: 7.5.0


getFlashMode()

getFlashMode() => Promise<{ flashMode: FlashMode; }>

Gets the current flash mode.

Returns: Promise<{ flashMode: CameraPreviewFlashMode; }>

Since: 7.5.0


removeAllListeners()

removeAllListeners() => Promise<void>

Removes all registered listeners.

Since: 7.5.0


setDeviceId(...)

setDeviceId(options: { deviceId: string; }) => Promise<void>

Switches the active camera to the one with the specified deviceId.

Param Type Description
options { deviceId: string; } - The ID of the device to switch to.

Since: 7.5.0


getDeviceId()

getDeviceId() => Promise<{ deviceId: string; }>

Gets the ID of the currently active camera device.

Returns: Promise<{ deviceId: string; }>

Since: 7.5.0


getPreviewSize()

getPreviewSize() => Promise<{ x: number; y: number; width: number; height: number; }>

Gets the current preview size and position.

Returns: Promise<{ x: number; y: number; width: number; height: number; }>

Since: 7.5.0


setPreviewSize(...)

setPreviewSize(options: { x?: number; y?: number; width: number; height: number; }) => Promise<{ width: number; height: number; x: number; y: number; }>

Sets the preview size and position.

Param Type Description
options { x?: number; y?: number; width: number; height: number; } The new position and dimensions.

Returns: Promise<{ width: number; height: number; x: number; y: number; }>

Since: 7.5.0


setFocus(...)

setFocus(options: { x: number; y: number; }) => Promise<void>

Sets the camera focus to a specific point in the preview.

Param Type Description
options { x: number; y: number; } - The focus options.

Since: 7.5.0


addListener('screenResize', ...)

addListener(eventName: "screenResize", listenerFunc: (data: { width: number; height: number; x: number; y: number; }) => void) => Promise<PluginListenerHandle>

Adds a listener for screen resize events.

Param Type Description
eventName 'screenResize' - The event name to listen for.
listenerFunc (data: { width: number; height: number; x: number; y: number; }) => void - The function to call when the event is triggered.

Returns: Promise<PluginListenerHandle>

Since: 7.5.0


addListener('orientationChange', ...)

addListener(eventName: "orientationChange", listenerFunc: (data: { orientation: DeviceOrientation; }) => void) => Promise<PluginListenerHandle>

Adds a listener for orientation change events.

Param Type Description
eventName 'orientationChange' - The event name to listen for.
listenerFunc (data: { orientation: DeviceOrientation; }) => void - The function to call when the event is triggered.

Returns: Promise<PluginListenerHandle>

Since: 7.5.0


deleteFile(...)

deleteFile(options: { path: string; }) => Promise<{ success: boolean; }>

Deletes a file at the given absolute path on the device. Use this to quickly clean up temporary images created with storeToFile. On web, this is not supported and will throw.

Param Type
options { path: string; }

Returns: Promise<{ success: boolean; }>

Since: 7.5.0


getSafeAreaInsets()

getSafeAreaInsets() => Promise<SafeAreaInsets>

Gets the safe area insets for devices. Returns the orientation-aware notch/camera cutout inset and the current orientation. In portrait mode: returns top inset (notch at top). In landscape mode: returns left inset (notch moved to side). This specifically targets the cutout area (notch, punch hole, etc.) that all modern phones have.

Android: Values returned in dp (logical pixels). iOS: Values returned in physical pixels, excluding status bar (only pure notch/cutout size).

Returns: Promise<SafeAreaInsets>


getOrientation()

getOrientation() => Promise<{ orientation: DeviceOrientation; }>

Gets the current device orientation in a cross-platform format.

Returns: Promise<{ orientation: DeviceOrientation; }>

Since: 7.5.0


getExposureModes()

getExposureModes() => Promise<{ modes: ExposureMode[]; }>

Returns the exposure modes supported by the active camera. Modes can include: 'locked', 'auto', 'continuous', 'custom'.

Returns: Promise<{ modes: ExposureMode[]; }>


getExposureMode()

getExposureMode() => Promise<{ mode: ExposureMode; }>

Returns the current exposure mode.

Returns: Promise<{ mode: ExposureMode; }>


setExposureMode(...)

setExposureMode(options: { mode: ExposureMode; }) => Promise<void>

Sets the exposure mode.

Param Type
options { mode: ExposureMode; }

getExposureCompensationRange()

getExposureCompensationRange() => Promise<{ min: number; max: number; step: number; }>

Returns the exposure compensation (EV bias) supported range.

Returns: Promise<{ min: number; max: number; step: number; }>


getExposureCompensation()

getExposureCompensation() => Promise<{ value: number; }>

Returns the current exposure compensation (EV bias).

Returns: Promise<{ value: number; }>


setExposureCompensation(...)

setExposureCompensation(options: { value: number; }) => Promise<void>

Sets the exposure compensation (EV bias). Value will be clamped to range.

Param Type
options { value: number; }

Interfaces

CameraPreviewOptions

Defines the configuration options for starting the camera preview.

Prop Type Description Default Since
parent string The parent element to attach the video preview to.
className string A CSS class name to add to the preview element.
width number The width of the preview in pixels. Defaults to the screen width.
height number The height of the preview in pixels. Defaults to the screen height.
x number The horizontal origin of the preview, in pixels.
y number The vertical origin of the preview, in pixels.
aspectRatio '4:3' | '16:9' The aspect ratio of the camera preview, '4:3' or '16:9' or 'fill'. Cannot be set if width or height is provided, otherwise the call will be rejected. Use setPreviewSize to adjust size after starting. 2.0.0
gridMode GridMode The grid overlay to display on the camera preview. "none" 2.1.0
includeSafeAreaInsets boolean Adjusts the y-position to account for safe areas (e.g., notches). false
toBack boolean If true, places the preview behind the webview. true
paddingBottom number Bottom padding for the preview, in pixels.
rotateWhenOrientationChanged boolean Whether to rotate the preview when the device orientation changes. true
position string The camera to use. "rear"
storeToFile boolean If true, saves the captured image to a file and returns the file path. If false, returns a base64 encoded string. false
disableExifHeaderStripping boolean If true, prevents the plugin from rotating the image based on EXIF data. false
disableAudio boolean If true, disables the audio stream, preventing audio permission requests. true
lockAndroidOrientation boolean If true, locks the device orientation while the camera is active. false
enableOpacity boolean If true, allows the camera preview's opacity to be changed. false
enableZoom boolean If true, enables pinch-to-zoom functionality on the preview. false
disableFocusIndicator boolean If true, disables the visual focus indicator when tapping to focus. false
deviceId string The deviceId of the camera to use. If provided, position is ignored.
initialZoomLevel number The initial zoom level when starting the camera preview. If the requested zoom level is not available, the native plugin will reject. 1.0 2.2.0
positioning CameraPositioning The vertical positioning of the camera preview. "center" 2.3.0
enableVideoMode boolean If true, enables video capture capabilities when the camera starts. false 7.11.0

ExifData

Represents EXIF data extracted from an image.

CameraPreviewPictureOptions

Defines the options for capturing a picture.

Prop Type Description Default Since
height number The maximum height of the picture in pixels. The image will be resized to fit within this height while maintaining aspect ratio. If not specified the captured image will match the preview's visible area.
width number The maximum width of the picture in pixels. The image will be resized to fit within this width while maintaining aspect ratio. If not specified the captured image will match the preview's visible area.
quality number The quality of the captured image, from 0 to 100. Does not apply to png format. 85
format PictureFormat The format of the captured image. "jpeg"
saveToGallery boolean If true, the captured image will be saved to the user's gallery. false 7.5.0
withExifLocation boolean If true, the plugin will attempt to add GPS location data to the image's EXIF metadata. This may prompt the user for location permissions. false 7.6.0

CameraSampleOptions

Defines the options for capturing a sample frame from the camera preview.

Prop Type Description Default
quality number The quality of the captured sample, from 0 to 100. 85

SupportedPictureSizes

Represents the supported picture sizes for a camera facing a certain direction.

Prop Type Description
facing string The camera direction ("front" or "rear").
supportedPictureSizes PictureSize[] A list of supported picture sizes for this camera.

PictureSize

Defines a standard picture size with width and height.

Prop Type Description
width number The width of the picture in pixels.
height number The height of the picture in pixels.

CameraOpacityOptions

Defines the options for setting the camera preview's opacity.

Prop Type Description Default
opacity number The opacity percentage, from 0.0 (fully transparent) to 1.0 (fully opaque). 1.0

CameraDevice

Represents a physical camera on the device (e.g., the front-facing camera).

Prop Type Description
deviceId string A unique identifier for the camera device.
label string A human-readable name for the camera device.
position CameraPosition The physical position of the camera on the device.
lenses CameraLens[] A list of all available lenses for this camera device.
minZoom number The overall minimum zoom factor available across all lenses on this device.
maxZoom number The overall maximum zoom factor available across all lenses on this device.
isLogical boolean Identifies whether the device is a logical camera (composed of multiple physical lenses).

CameraLens

Represents a single camera lens on a device. A {@link CameraDevice} can have multiple lenses.

Prop Type Description
label string A human-readable name for the lens, e.g., "Ultra-Wide".
deviceType DeviceType The type of the camera lens.
focalLength number The focal length of the lens in millimeters.
baseZoomRatio number The base zoom factor for this lens (e.g., 0.5 for ultra-wide, 1.0 for wide).
minZoom number The minimum zoom factor supported by this specific lens.
maxZoom number The maximum zoom factor supported by this specific lens.

LensInfo

Represents the detailed information of the currently active lens.

Prop Type Description
focalLength number The focal length of the active lens in millimeters.
deviceType DeviceType The device type of the active lens.
baseZoomRatio number The base zoom ratio of the active lens (e.g., 0.5x, 1.0x).
digitalZoom number The current digital zoom factor applied on top of the base zoom.

PluginListenerHandle

Prop Type
remove () => Promise<void>

SafeAreaInsets

Represents safe area insets for devices. Android: Values are expressed in logical pixels (dp) to match JS layout units. iOS: Values are expressed in physical pixels and exclude status bar.

Prop Type Description
orientation number Current device orientation (1 = portrait, 2 = landscape, 0 = unknown).
top number Orientation-aware notch/camera cutout inset (excluding status bar). In portrait mode: returns top inset (notch at top). In landscape mode: returns left inset (notch at side). Android: Value in dp, iOS: Value in pixels (status bar excluded).

Type Aliases

GridMode

"none" | "3x3" | "4x4"

CameraPosition

"rear" | "front"

CameraPositioning

"center" | "top" | "bottom"

PictureFormat

"jpeg" | "png"

CameraPreviewFlashMode

The available flash modes for the camera. 'torch' is a continuous light mode.

"off" | "on" | "auto" | "torch"

FlashMode

CameraPreviewFlashMode

DeviceOrientation

Canonical device orientation values across platforms.

"portrait" | "landscape" | "landscape-left" | "landscape-right" | "portrait-upside-down" | "unknown"

ExposureMode

Reusable exposure mode type for cross-platform support.

"AUTO" | "LOCK" | "CONTINUOUS" | "CUSTOM"

Enums

DeviceType

Members Value
ULTRA_WIDE "ultraWide"
WIDE_ANGLE "wideAngle"
TELEPHOTO "telephoto"
TRUE_DEPTH "trueDepth"
DUAL "dual"
DUAL_WIDE "dualWide"
TRIPLE "triple"

About

Capacitor plugin that allows camera interaction from Javascript and HTML

Topics

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Sponsor this project

 

Contributors 50