Feature: Camera & Image Capture
Relevant source files
The following files were used as context for generating this wiki page:- app/src/main/java/com/musagenius/ocrapp/data/camera/CameraManager.kt
- app/src/main/java/com/musagenius/ocrapp/presentation/ui/camera/CameraScreen.kt
- app/src/main/java/com/musagenius/ocrapp/presentation/viewmodel/CameraViewModel.kt
- app/src/main/java/com/musagenius/ocrapp/presentation/ui/camera/CameraState.kt
- app/src/main/java/com/musagenius/ocrapp/data/camera/DocumentEdgeDetector.kt
- app/src/main/java/com/musagenius/ocrapp/MainActivity.kt
- app/src/main/AndroidManifest.xml
The Camera & Image Capture feature is a core component of the OCR Android App, providing the primary user interface for acquiring images to be processed for text recognition. It is built using CameraX for robust camera operations and Jetpack Compose for the user interface, following an MVVM architecture.
This feature is responsible for displaying a live camera preview, handling user interactions for capturing images, managing camera settings like flash and zoom, and providing real-time feedback such as document edge detection and low-light warnings. Once an image is captured, it is compressed and its URI is passed to the OCR Processing flow.
Sources: app/src/main/java/com/musagenius/ocrapp/presentation/ui/camera/CameraScreen.kt, app/src/main/java/com/musagenius/ocrapp/data/camera/CameraManager.kt
Architecture
The feature follows a Model-View-ViewModel (MVVM) pattern, separating UI logic from business logic.
- View (
CameraScreen.kt): A Jetpack Compose screen that displays the camera preview and UI controls. It observesCameraUiStatefrom theCameraViewModeland sends user actions asCameraEvents. - ViewModel (
CameraViewModel.kt): Manages the UI state, handles all user events, and communicates with theCameraManagerto perform camera operations. - Manager (
CameraManager.kt): A data-layer class that encapsulates all CameraX API interactions. It manages the camera lifecycle, use cases (Preview, ImageCapture, ImageAnalysis), and hardware controls. - State/Events (
CameraState.kt): Contains data classes for the UI state (CameraUiState) and a sealed class for UI events (CameraEvent), ensuring a unidirectional data flow.
Sources: app/src/main/java/com/musagenius/ocrapp/presentation/ui/camera/CameraScreen.kt, app/src/main/java/com/musagenius/ocrapp/presentation/viewmodel/CameraViewModel.kt, app/src/main/java/com/musagenius/ocrapp/data/camera/CameraManager.kt, app/src/main/java/com/musagenius/ocrapp/presentation/ui/camera/CameraState.kt
Component Interaction Diagram
This diagram illustrates the architectural relationship between the main components of the camera feature.
State and Event Management
The camera feature uses a unidirectional data flow managed by the CameraViewModel. The UI state is encapsulated in CameraUiState and all user interactions are represented by CameraEvent.
Sources: app/src/main/java/com/musagenius/ocrapp/presentation/ui/camera/CameraState.kt
CameraUiState
This data class represents the complete state of the camera screen at any given time.
| Property | Type | Description |
|---|---|---|
isLoading | Boolean | True if the camera is currently being initialized. |
capturedImageUri | Uri? | The URI of the last captured and compressed image. |
error | String? | An error message to be displayed to the user. |
flashMode | FlashMode | The current flash mode (ON, OFF, AUTO). |
isProcessing | Boolean | True when an image is being captured and processed. |
zoomRatio | Float | The current camera zoom ratio. |
cameraFacing | CameraFacing | The current camera direction (BACK, FRONT). |
showGridOverlay | Boolean | Toggles the visibility of the grid overlay. |
showDocumentOverlay | Boolean | Toggles the visibility of the document edge detection overlay. |
documentCorners | DocumentCorners? | The coordinates of the detected document corners. |
lightingCondition | LightingCondition | The detected lighting condition (GOOD, LOW, VERY_LOW). |
resolution | CameraResolution | The selected camera capture resolution. |
Sources: app/src/main/java/com/musagenius/ocrapp/presentation/ui/camera/CameraState.kt:8-27
CameraEvent
This sealed class defines all possible user actions that can be triggered from the CameraScreen.
| Event | Description |
|---|---|
CaptureImage | Triggered when the user taps the capture button. |
ToggleFlash | Cycles through the available flash modes. |
PickFromGallery | Initiates picking an image from the device gallery. |
SetZoom(ratio) | Sets the camera zoom to the specified ratio. |
TapToFocus(x, y) | Requests focus at a specific point on the preview. |
FlipCamera | Switches between the front and back cameras. |
ToggleGridOverlay | Toggles the grid overlay visibility. |
ToggleDocumentOverlay | Toggles the document detection overlay visibility. |
SetResolution(resolution) | Changes the camera resolution and restarts the camera. |
Sources: app/src/main/java/com/musagenius/ocrapp/presentation/ui/camera/CameraState.kt:94-111
Core Functionalities
Camera Initialization
The camera is initialized in the CameraViewModel by calling cameraManager.startCamera(). This function sets up and binds three CameraX use cases to the lifecycle of the CameraScreen.
Preview: Displays the live camera feed on aPreviewView.ImageCapture: Handles taking high-quality pictures.ImageAnalysis: Provides a stream of frames for real-time analysis, used for document edge and low-light detection.
The CameraManager is ActivityRetainedScoped, ensuring that camera resources are properly managed across configuration changes.
Sources: app/src/main/java/com/musagenius/ocrapp/data/camera/CameraManager.kt:65-126, app/src/main/java/com/musagenius/ocrapp/presentation/viewmodel/CameraViewModel.kt:66-99
Image Capture Flow
The following diagram shows the sequence of events when a user captures an image.
Real-time Image Analysis
The CameraManager uses the ImageAnalysis use case to provide real-time feedback on the camera preview. It processes frames on a background thread to avoid blocking the UI.
- Document Edge Detection: The
DocumentEdgeDetectorclass processes image frames to find the corners of a rectangular document. It uses a simple brightness gradient to detect edges and calculates a confidence score. The detected corners are then drawn on an overlay in theCameraScreen. - Low-Light Detection: The
LowLightDetectoranalyzes frame brightness to determine the ambient lighting conditions. If low light is detected, a warning is displayed on theCameraScreen, prompting the user to enable the flash.
Callbacks (edgeDetectionCallback, lightingConditionCallback) are used to send the results from the CameraManager back to the CameraViewModel, which then updates the CameraUiState.
Sources: app/src/main/java/com/musagenius/ocrapp/data/camera/CameraManager.kt:254-301, app/src/main/java/com/musagenius/ocrapp/data/camera/DocumentEdgeDetector.kt, app/src/main/java/com/musagenius/ocrapp/presentation/viewmodel/CameraViewModel.kt:222-234
Permissions
The application declares the necessary camera permissions in the AndroidManifest.xml.
<!-- app/src/main/AndroidManifest.xml:8-14 -->
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
<!-- Permissions -->
<uses-permission android:name="android.permission.CAMERA" />
The CameraScreen uses the com.google.accompanist.permissions library to handle the runtime permission request flow. It displays a rationale dialog if the user has previously denied the permission and provides a path to the app settings if the permission is permanently denied.
Sources: app/src/main/AndroidManifest.xml:8-14, app/src/main/java/com/musagenius/ocrapp/presentation/ui/camera/CameraScreen.kt:43-44, 61-89
Navigation
Navigation from the camera screen is handled in MainActivity.kt.
- On Image Capture: After a successful capture, the app navigates to the
Screen.Resultsdestination, passing the URI of the captured image. - On Gallery Selection: If the user selects an image from the gallery, the app navigates to the
Screen.ImageEditordestination, allowing for cropping and rotation before OCR.
// app/src/main/java/com/musagenius/ocrapp/MainActivity.kt:45-54
composable(Screen.Camera.route) {
CameraScreen(
onImageCaptured = { imageUri ->
// Navigate to results screen with the captured image
navController.navigate(Screen.Results.createRoute(imageUri.toString()))
},
onGalleryImageSelected = { imageUri ->
// Navigate to image editor for gallery images
navController.navigate(Screen.ImageEditor.createRoute(imageUri.toString()))
},
...
)
}
Sources: app/src/main/java/com/musagenius/ocrapp/MainActivity.kt:43-65