Skip to content

CameraController API

Low-level camera operations. Available when camera state is Ready.

Accessing Controller

val cameraState by rememberCameraKState()

when (cameraState) {
    is CameraKState.Ready -> {
        val controller = (cameraState as CameraKState.Ready).controller
        // Use controller here
    }
}

Image Capture

takePictureToFile()

Recommended -- Captures image directly to file.

suspend fun takePictureToFile(): ImageCaptureResult

Returns: - ImageCaptureResult.SuccessWithFile(filePath: String) - ImageCaptureResult.Error(exception: Exception)

Example:

scope.launch {
    when (val result = controller.takePictureToFile()) {
        is ImageCaptureResult.SuccessWithFile -> {
            println("Saved: ${result.filePath}")
        }
        is ImageCaptureResult.Error -> {
            println("Error: ${result.exception.message}")
        }
    }
}

Benefits: - 2-3 seconds faster than takePicture() - No ByteArray conversion - Lower memory usage

takePicture()

Deprecated -- Returns image as ByteArray.

@Deprecated("Use takePictureToFile()")
suspend fun takePicture(): ImageCaptureResult

Returns: - ImageCaptureResult.Success(byteArray: ByteArray) - ImageCaptureResult.Error(exception: Exception)

Zoom Control

setZoom()

fun setZoom(zoomRatio: Float)

Sets zoom level between 1.0 and maxZoom.

Parameters: - zoomRatio -- Zoom level (1.0 = no zoom)

Example:

controller.setZoom(2.5f)  // 2.5x zoom

getZoom()

fun getZoom(): Float

Returns current zoom level.

Example:

val currentZoom = controller.getZoom()  // e.g., 2.5

getMaxZoom()

fun getMaxZoom(): Float

Returns maximum supported zoom.

Example:

val maxZoom = controller.getMaxZoom()  // e.g., 10.0

Flash Control

setFlashMode()

fun setFlashMode(mode: FlashMode)

Sets flash mode.

Parameters: - FlashMode.ON -- Always fire flash - FlashMode.OFF -- Flash disabled - FlashMode.AUTO -- Flash in low light

Example:

controller.setFlashMode(FlashMode.ON)

getFlashMode()

fun getFlashMode(): FlashMode?

Returns current flash mode or null if not available.

Example:

val flashMode = controller.getFlashMode()
when (flashMode) {
    FlashMode.ON -> println("Flash enabled")
    FlashMode.OFF -> println("Flash disabled")
    FlashMode.AUTO -> println("Flash automatic")
    null -> println("Flash not available")
}

toggleFlashMode()

fun toggleFlashMode()

Cycles through: OFF -> ON -> AUTO -> OFF

Example:

IconButton(onClick = { controller.toggleFlashMode() }) {
    Icon(Icons.Default.FlashOn, "Toggle Flash")
}

Torch Control

setTorchMode()

fun setTorchMode(mode: TorchMode)

Sets torch (flashlight) mode.

Parameters: - TorchMode.ON -- Torch enabled - TorchMode.OFF -- Torch disabled

Example:

controller.setTorchMode(TorchMode.ON)

getTorchMode()

fun getTorchMode(): TorchMode?

Returns current torch mode or null if not available.

toggleTorchMode()

fun toggleTorchMode()

Toggles torch ON / OFF.

Example:

IconButton(onClick = { controller.toggleTorchMode() }) {
    val isOn = controller.getTorchMode() == TorchMode.ON
    Icon(
        if (isOn) Icons.Default.FlashlightOn else Icons.Default.FlashlightOff,
        "Toggle Torch"
    )
}

Camera Lens

getCameraLens()

fun getCameraLens(): CameraLens?

Returns current camera lens.

toggleCameraLens()

fun toggleCameraLens()

Switches between front and back.

Example:

IconButton(onClick = { controller.toggleCameraLens() }) {
    Icon(Icons.Default.Cameraswitch, "Switch Camera")
}

Session Management

startSession()

fun startSession()

Starts camera session. Called automatically.

stopSession()

fun stopSession()

Stops camera session.

Example:

DisposableEffect(Unit) {
    onDispose {
        controller.stopSession()
    }
}

Listeners

addImageCaptureListener()

fun addImageCaptureListener(listener: (ByteArray) -> Unit)

Adds listener for captured images. Used by plugins.

Example:

controller.addImageCaptureListener { imageData ->
    processImage(imageData)
}

Other Methods

initializeControllerPlugins()

fun initializeControllerPlugins()

Initializes controller-level plugins. Called automatically during setup.

Cleanup

cleanup()

fun cleanup()

Releases all resources. Called automatically on dispose.

Example:

DisposableEffect(Unit) {
    onDispose {
        controller.cleanup()
    }
}

Complete Example

@Composable
fun CompleteControllerExample() {
    val scope = rememberCoroutineScope()
    val cameraState by rememberCameraKState()

    Box(modifier = Modifier.fillMaxSize()) {
        when (val state = cameraState) {
            is CameraKState.Ready -> {
                val controller = state.controller
                val uiState = state.uiState
                val maxZoom = remember { controller.getMaxZoom() }
                var currentZoom by remember { mutableStateOf(1.0f) }

                CameraPreviewView(
                    controller = controller,
                    modifier = Modifier
                        .fillMaxSize()
                        .pointerInput(Unit) {
                            detectTransformGestures { _, _, zoom, _ ->
                                currentZoom = (currentZoom * zoom).coerceIn(1f, maxZoom)
                                controller.setZoom(currentZoom)
                            }
                        }
                )

                // Top controls
                Row(
                    modifier = Modifier
                        .align(Alignment.TopEnd)
                        .padding(16.dp),
                    horizontalArrangement = Arrangement.spacedBy(8.dp)
                ) {
                    // Flash toggle
                    IconButton(onClick = { controller.toggleFlashMode() }) {
                        Icon(
                            when (controller.getFlashMode()) {
                                FlashMode.ON -> Icons.Default.FlashOn
                                FlashMode.OFF -> Icons.Default.FlashOff
                                FlashMode.AUTO -> Icons.Default.FlashAuto
                                else -> Icons.Default.FlashOff
                            },
                            "Flash"
                        )
                    }

                    // Camera switch
                    IconButton(onClick = { controller.toggleCameraLens() }) {
                        Icon(Icons.Default.Cameraswitch, "Switch")
                    }

                    // Torch toggle
                    IconButton(onClick = { controller.toggleTorchMode() }) {
                        Icon(
                            if (controller.getTorchMode() == TorchMode.ON)
                                Icons.Default.FlashlightOn
                            else Icons.Default.FlashlightOff,
                            "Torch"
                        )
                    }
                }

                // Zoom indicator
                Text(
                    text = "${String.format("%.1f", currentZoom)}x",
                    modifier = Modifier
                        .align(Alignment.TopCenter)
                        .padding(16.dp),
                    color = Color.White
                )

                // Capture button
                FloatingActionButton(
                    onClick = {
                        scope.launch {
                            when (val result = controller.takePictureToFile()) {
                                is ImageCaptureResult.SuccessWithFile -> {
                                    println("Saved: ${result.filePath}")
                                }
                                is ImageCaptureResult.Error -> {
                                    println("Error: ${result.exception.message}")
                                }
                            }
                        }
                    },
                    modifier = Modifier
                        .align(Alignment.BottomCenter)
                        .padding(32.dp)
                ) {
                    Icon(Icons.Default.CameraAlt, "Capture")
                }
            }

            is CameraKState.Error -> {
                Column(
                    modifier = Modifier.fillMaxSize(),
                    verticalArrangement = Arrangement.Center,
                    horizontalAlignment = Alignment.CenterHorizontally
                ) {
                    Text("Camera error: ${state.message}")
                    if (state.isRetryable) {
                        Button(onClick = { /* retry */ }) {
                            Text("Retry")
                        }
                    }
                }
            }

            CameraKState.Initializing -> CircularProgressIndicator()
        }
    }
}

Platform Availability

Method Android iOS Desktop
takePictureToFile() Yes Yes Yes
setZoom() Yes Yes Limited
setFlashMode() Yes (rear) Yes (rear) No
setTorchMode() Yes (rear) Yes (rear) No
toggleCameraLens() Yes Yes Limited

See Also