# CameraXViewfinder

## Functions summary

|---|---|
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable https://developer.android.com/reference/kotlin/androidx/camera/compose/CameraXViewfinder.composable#CameraXViewfinder(androidx.camera.core.SurfaceRequest,androidx.compose.ui.Modifier,androidx.camera.viewfinder.core.ImplementationMode,androidx.camera.viewfinder.compose.MutableCoordinateTransformer,androidx.compose.ui.Alignment,androidx.compose.ui.layout.ContentScale,kotlin.Function1,kotlin.Boolean,kotlin.Function2,kotlin.Long,kotlin.Boolean,kotlin.Function1,kotlin.Function1,kotlin.Function0)( surfaceRequest: https://developer.android.com/reference/kotlin/androidx/camera/core/SurfaceRequest, modifier: https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier, implementationMode: https://developer.android.com/reference/kotlin/androidx/camera/viewfinder/core/ImplementationMode, coordinateTransformer: https://developer.android.com/reference/kotlin/androidx/camera/viewfinder/compose/MutableCoordinateTransformer?, alignment: https://developer.android.com/reference/kotlin/androidx/compose/ui/Alignment, contentScale: https://developer.android.com/reference/kotlin/androidx/compose/ui/layout/ContentScale, onStreamStateChanged: (https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html, isTapToFocusEnabled: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html, onTapToFocus: (https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset, https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html, autoCancelDurationMillis: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-long/index.html, isPinchToZoomEnabled: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html, onZoomRatioChanged: (https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html, onScreenFlashReady: (https://developer.android.com/reference/kotlin/androidx/camera/core/ImageCapture.ScreenFlash) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html, onRelease: () -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html )` An adapter composable that displays frames from CameraX by completing provided `https://developer.android.com/reference/kotlin/androidx/camera/core/SurfaceRequest`s. |

## Functions

### CameraXViewfinder

Artifact: [androidx.camera:camera-compose](https://developer.android.com/jetpack/androidx/releases/camera) [View Source](https://cs.android.com/search?q=file:androidx/camera/compose/CameraXViewfinder.kt+function:CameraXViewfinder)

```
@Composable
fun CameraXViewfinder(
    surfaceRequest: SurfaceRequest,
    modifier: Modifier = Modifier,
    implementationMode: ImplementationMode = CameraImplementationModeCompat.chooseCompatibleMode(surfaceRequest.camera.cameraInfo),
    coordinateTransformer: MutableCoordinateTransformer? = null,
    alignment: Alignment = Alignment.Center,
    contentScale: ContentScale = ContentScale.Crop,
    onStreamStateChanged: (Int) -> Unit = {},
    isTapToFocusEnabled: Boolean = false,
    onTapToFocus: (Offset, Int) -> Unit = { _, _ -> },
    autoCancelDurationMillis: Long = 5000,
    isPinchToZoomEnabled: Boolean = false,
    onZoomRatioChanged: (Float) -> Unit = {},
    onScreenFlashReady: (ImageCapture.ScreenFlash) -> Unit = {},
    onRelease: () -> Unit = {}
): Unit
```

An adapter composable that displays frames from CameraX by completing provided `https://developer.android.com/reference/kotlin/androidx/camera/core/SurfaceRequest`s.

This is a wrapper around `https://developer.android.com/reference/kotlin/androidx/camera/viewfinder/compose/Viewfinder.composable#Viewfinder(androidx.camera.viewfinder.core.ViewfinderSurfaceRequest,androidx.compose.ui.Modifier,androidx.camera.viewfinder.core.TransformationInfo,androidx.camera.viewfinder.compose.MutableCoordinateTransformer,androidx.compose.ui.Alignment,androidx.compose.ui.layout.ContentScale,kotlin.Function1)` that will convert a CameraX `https://developer.android.com/reference/kotlin/androidx/camera/core/SurfaceRequest` internally into a `https://developer.android.com/reference/kotlin/androidx/camera/viewfinder/core/ViewfinderSurfaceRequest`. Additionally, all interactions normally handled through the `https://developer.android.com/reference/kotlin/androidx/camera/viewfinder/core/ViewfinderSurfaceRequest` will be derived from the `https://developer.android.com/reference/kotlin/androidx/camera/core/SurfaceRequest`.

If `https://developer.android.com/reference/kotlin/androidx/camera/compose/package-summary#CameraXViewfinder(androidx.camera.core.SurfaceRequest,androidx.compose.ui.Modifier,androidx.camera.viewfinder.core.ImplementationMode,androidx.camera.viewfinder.compose.MutableCoordinateTransformer,androidx.compose.ui.Alignment,androidx.compose.ui.layout.ContentScale,kotlin.Function1,kotlin.Boolean,kotlin.Function2,kotlin.Long,kotlin.Boolean,kotlin.Function1,kotlin.Function1,kotlin.Function0)` is changed while the provided `https://developer.android.com/reference/kotlin/androidx/camera/compose/package-summary#CameraXViewfinder(androidx.camera.core.SurfaceRequest,androidx.compose.ui.Modifier,androidx.camera.viewfinder.core.ImplementationMode,androidx.camera.viewfinder.compose.MutableCoordinateTransformer,androidx.compose.ui.Alignment,androidx.compose.ui.layout.ContentScale,kotlin.Function1,kotlin.Boolean,kotlin.Function2,kotlin.Long,kotlin.Boolean,kotlin.Function1,kotlin.Function1,kotlin.Function0)` has been fulfilled, the surface request will be invalidated as if `https://developer.android.com/reference/kotlin/androidx/camera/core/SurfaceRequest#invalidate()` has been called. This will allow CameraX to know that a new surface request is required since the underlying viewfinder implementation will be providing a new surface.

This specific overload provides full control over advanced viewfinder features such as pinch-to-zoom, tap-to-focus gestures, and screen flash.

Example usage:

```kotlin
import androidx.camera.compose.CameraXViewfinder
import androidx.camera.core.Preview
import androidx.camera.core.SurfaceRequest
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.lifecycle.ViewModel

class PreviewViewModel : ViewModel() {
    private val _surfaceRequests = MutableStateFlow<SurfaceRequest?>(null)

    val surfaceRequests: StateFlow<SurfaceRequest?>
        get() = _surfaceRequests.asStateFlow()

    // Connects a CameraX Preview use case to this ViewModel to publish SurfaceRequests
    fun bindPreview(preview: Preview) {
        preview.setSurfaceProvider { newRequest -> _surfaceRequests.value = newRequest }
    }
}

@Composable
fun MyCameraViewfinder(viewModel: PreviewViewModel, modifier: Modifier = Modifier) {
    val currentSurfaceRequest: SurfaceRequest? by viewModel.surfaceRequests.collectAsState()

    Box(modifier = modifier) {
        currentSurfaceRequest?.let { surfaceRequest ->
            CameraXViewfinder(
                surfaceRequest = surfaceRequest,
                modifier = Modifier.fillMaxSize(),
                isTapToFocusEnabled = true,
                isPinchToZoomEnabled = true,
                onTapToFocus = { offset, state ->
                    // Respond to tap-to-focus (e.g. update focus UI indicator state)
                },
                onZoomRatioChanged = { ratio ->
                    // Respond to zoom ratio changes (e.g. update zoom UI indicator)
                },
                onScreenFlashReady = { screenFlash ->
                    // Coordinate screen flash callbacks with camera capture lifecycle
                },
                onRelease = {
                    // Clear references to screen flash to prevent leaks
                },
            )
        }

        // Draw a focus indicator when a focus point is active.
    }
}

val viewModel = remember { PreviewViewModel() }
MyCameraViewfinder(viewModel = viewModel)
```

| Parameters |
|---|---|
| `surfaceRequest: https://developer.android.com/reference/kotlin/androidx/camera/core/SurfaceRequest` | The surface request from CameraX |
| `modifier: https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier = Modifier` | The `https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier` to be applied to this viewfinder |
| `implementationMode: https://developer.android.com/reference/kotlin/androidx/camera/viewfinder/core/ImplementationMode = CameraImplementationModeCompat.chooseCompatibleMode(surfaceRequest.camera.cameraInfo)` | The `https://developer.android.com/reference/kotlin/androidx/camera/viewfinder/core/ImplementationMode` to be used by this viewfinder. By default, this is chosen automatically based on the device's capabilities. The default behavior prefers the higher-performance `https://developer.android.com/reference/kotlin/androidx/camera/viewfinder/core/ImplementationMode#EXTERNAL` mode, but will fall back to `https://developer.android.com/reference/kotlin/androidx/camera/viewfinder/core/ImplementationMode#EMBEDDED` if the camera hardware level is `https://developer.android.com/reference/android/hardware/camera2/CameraMetadata.html#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY`, or on devices with other known compatibility issues (such as on API level 24 and below). Explicitly setting a mode will override this compatibility logic and may have performance or correctness implications on some devices. |
| `coordinateTransformer: https://developer.android.com/reference/kotlin/androidx/camera/viewfinder/compose/MutableCoordinateTransformer? = null` | The `https://developer.android.com/reference/kotlin/androidx/camera/viewfinder/compose/MutableCoordinateTransformer` used to map offsets of this viewfinder to the source coordinates of the data being provided to the surface that fulfills `https://developer.android.com/reference/kotlin/androidx/camera/compose/package-summary#CameraXViewfinder(androidx.camera.core.SurfaceRequest,androidx.compose.ui.Modifier,androidx.camera.viewfinder.core.ImplementationMode,androidx.camera.viewfinder.compose.MutableCoordinateTransformer,androidx.compose.ui.Alignment,androidx.compose.ui.layout.ContentScale,kotlin.Function1,kotlin.Boolean,kotlin.Function2,kotlin.Long,kotlin.Boolean,kotlin.Function1,kotlin.Function1,kotlin.Function0)` |
| `alignment: https://developer.android.com/reference/kotlin/androidx/compose/ui/Alignment = Alignment.Center` | Optional alignment parameter used to place the camera feed in the given bounds of the `https://developer.android.com/reference/kotlin/androidx/camera/compose/CameraXViewfinder.composable#CameraXViewfinder(androidx.camera.core.SurfaceRequest,androidx.compose.ui.Modifier,androidx.camera.viewfinder.core.ImplementationMode,androidx.camera.viewfinder.compose.MutableCoordinateTransformer,androidx.compose.ui.Alignment,androidx.compose.ui.layout.ContentScale,kotlin.Function1,kotlin.Boolean,kotlin.Function2,kotlin.Long,kotlin.Boolean,kotlin.Function1,kotlin.Function1,kotlin.Function0)`. Defaults to `https://developer.android.com/reference/kotlin/androidx/compose/ui/Alignment#Center()`. |
| `contentScale: https://developer.android.com/reference/kotlin/androidx/compose/ui/layout/ContentScale = ContentScale.Crop` | Optional scale parameter used to determine the aspect ratio scaling to be used to fit the camera feed in the bounds of the `https://developer.android.com/reference/kotlin/androidx/camera/compose/CameraXViewfinder.composable#CameraXViewfinder(androidx.camera.core.SurfaceRequest,androidx.compose.ui.Modifier,androidx.camera.viewfinder.core.ImplementationMode,androidx.camera.viewfinder.compose.MutableCoordinateTransformer,androidx.compose.ui.Alignment,androidx.compose.ui.layout.ContentScale,kotlin.Function1,kotlin.Boolean,kotlin.Function2,kotlin.Long,kotlin.Boolean,kotlin.Function1,kotlin.Function1,kotlin.Function0)`. Defaults to `https://developer.android.com/reference/kotlin/androidx/compose/ui/layout/ContentScale#Crop()`. |
| `onStreamStateChanged: (https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html = {}` | Callback invoked when the preview stream state changes. Provides the current `https://developer.android.com/reference/kotlin/androidx/camera/core/Preview.StreamState`. |
| `isTapToFocusEnabled: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html = false` | Whether the tap-to-focus gesture is enabled. |
| `onTapToFocus: (https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset, https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html = { _, _ -> }` | A callback invoked when a tap-to-focus action is triggered. It provides the tap `https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset` and an integer representing the current focus state. See `https://developer.android.com/reference/kotlin/androidx/camera/viewfinder/core/FocusState` for possible values. |
| `autoCancelDurationMillis: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-long/index.html = 5000` | The auto-cancel duration of focus/metering in milliseconds. Defaults to 5000L. |
| `isPinchToZoomEnabled: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html = false` | Whether the pinch-to-zoom gesture is enabled. |
| `onZoomRatioChanged: (https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html = {}` | A callback invoked when the `https://developer.android.com/reference/kotlin/androidx/camera/compose/CameraXViewfinder.composable#CameraXViewfinder(androidx.camera.core.SurfaceRequest,androidx.compose.ui.Modifier,androidx.camera.viewfinder.core.ImplementationMode,androidx.camera.viewfinder.compose.MutableCoordinateTransformer,androidx.compose.ui.Alignment,androidx.compose.ui.layout.ContentScale,kotlin.Function1,kotlin.Boolean,kotlin.Function2,kotlin.Long,kotlin.Boolean,kotlin.Function1,kotlin.Function1,kotlin.Function0)`'s pinch-to-zoom gesture scales the zoom ratio, providing the updated zoom ratio. This callback is only invoked during the active zooming state. |
| `onScreenFlashReady: (https://developer.android.com/reference/kotlin/androidx/camera/core/ImageCapture.ScreenFlash) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html = {}` | A callback invoked when the screen flash feature is ready to apply, providing the `https://developer.android.com/reference/kotlin/androidx/camera/core/ImageCapture.ScreenFlash` implementation to be used with ImageCapture. |
| `onRelease: () -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html = {}` | A callback invoked when the `https://developer.android.com/reference/kotlin/androidx/camera/compose/CameraXViewfinder.composable#CameraXViewfinder(androidx.camera.core.SurfaceRequest,androidx.compose.ui.Modifier,androidx.camera.viewfinder.core.ImplementationMode,androidx.camera.viewfinder.compose.MutableCoordinateTransformer,androidx.compose.ui.Alignment,androidx.compose.ui.layout.ContentScale,kotlin.Function1,kotlin.Boolean,kotlin.Function2,kotlin.Long,kotlin.Boolean,kotlin.Function1,kotlin.Function1,kotlin.Function0)` is permanently removed from the composition, indicating that any references to resources (like `https://developer.android.com/reference/kotlin/androidx/camera/core/ImageCapture.ScreenFlash`) should be cleared. |