A single, stand-alone Android app that showcases the Camera2 and CameraX APIs through a catalog of small, self-contained, Compose-first samples. Each sample focuses on one feature and reuses a shared camera-scaffolding layer, so adding a new sample means writing the feature — not the boilerplate.
The home catalog in the "Console" theme — a violet accent, monospace metadata, a bordered featured card, and a dense 2-column grid. The filter pills narrow the catalog by category, and samples are grouped CameraX-first, Camera2 below.
- Clone the repository.
- Open it in a recent Android Studio.
- Run the
appconfiguration on a device or emulator. Camera-dependent samples (extensions, slow-motion, ML) behave best on a physical device; emulators with a virtual camera cover the basics.
No Firebase / google-services.json is required.
Filter the catalog by category (Images / Video / ML / Graphics / Extensions / Controls) on the home screen. Within each view, CameraX samples are listed first and Camera2 below.
| Sample | API | What it shows |
|---|---|---|
| Take a Photo | CameraX / Camera2 | Preview, tap-to-focus, capture a still |
| Take a Video | CameraX (Recorder) / Camera2 (MediaRecorder) | Record video to DCIM/Camera |
| Pause/Resume | CameraX (Recorder) | Pause and resume a recording mid-capture |
| Slow Motion | Camera2 | High-speed (constrained) recording |
| HDR Video | CameraX / Camera2 | Record & play back 10-bit HDR video (DynamicRange / DynamicRangeProfiles) |
| Video Stabilization | CameraX | Steadier footage via preview + video stabilization |
| Flip While Recording | CameraX | Switch front/back cameras without interrupting the recording |
| QR Scanner | CameraX / Camera2 + ML Kit | Real-time barcode/QR detection with overlay |
| Image Labeling | CameraX + ML Kit | Real-time on-device labels via ImageAnalysis |
| Luminosity | CameraX | Scene-brightness meter from the ImageAnalysis Y plane |
| Green Screen | CameraX + ML Kit | Concurrent cameras: segment the front-camera subject over the live back camera |
| Extensions | CameraX / Camera2 | Night / Bokeh / HDR / Face Retouch / Auto |
| Ultra HDR | CameraX | Gain-map Ultra HDR (JPEG_R) capture + a viewer to compare SDR / gain map / Ultra HDR |
| Effects | CameraX | Live color filters (grayscale, sepia, invert, …) via ImageAnalysis + ColorMatrix |
| Viewfinder Effects | Camera2 | Real-time frame processing on the live preview |
| Concurrent Camera | CameraX | Front + back preview at once (picture-in-picture) |
| RAW / DNG | Camera2 | RAW_SENSOR → DNG via DngCreator, then an in-app viewer/editor (re-expose, re-white-balance) |
| Zoom & Torch | CameraX / Camera2 | Zoom ratio slider + torch toggle |
| Exposure | CameraX | Exposure-compensation slider |
| Low-Light Boost | CameraX | Brighten dark scenes with CameraControl low-light boost |
| Feature Combination | CameraX | Query & apply CameraX feature-group combos (HDR, 60fps, stabilization, Ultra HDR) |
| Manual Controls | Camera2 | Manual ISO / shutter / focus distance |
Samples that depend on optional hardware (extensions, high-speed recording, manual sensor) detect support at runtime and show a friendly "not supported on this device" state instead of crashing.
Every sample is a Gradle library module under samples/{api}-{feature}/
(package com.android.{api}.{feature}) exposing a single {Api}{Feature}Screen() composable. It
follows the layered, unidirectional pattern in android_architecture.md:
{Feature}UiState— asealed interfaceof states (Initial, feature states,Error).{Feature}ViewModel— a@HiltViewModelexposing a singleStateFlow<UiState>; no Android/lifecycle references.{Feature}Controller— a@Stablestate-holder that owns the camera SDK lifecycle, created with aremember{Feature}Controller(...)composable.{Feature}Screen— collects state withcollectAsStateWithLifecycle, wraps everything in the shared scaffold, and renders with awhen(state).
The scaffolding that used to be copy-pasted into every sample lives in three shared modules, so a new sample focuses only on its feature:
:core-theme— the design system: the Material 3 color scheme with the violet "Console" accent, Space Grotesk / Space Mono typography (via Google Fonts), and theAISampleCatalogThemewrapper.:core-camera— camera plumbing:BaseCamera2Controller(background thread, open/close, viewfinder transform, tap-to-focus, session creation),Camera2Preview/CameraXPreview,ImageUtils(Image/ImageProxy→Bitmap),MediaStoreSaver,rememberDisplayRotation(), andCameraPermissions. It re-exports the common CameraX/Camera2 libraries.:core-ui— API-agnostic Compose chrome:CameraSampleScaffold(permission flow + surface), the viewfinder HUD (FocusIndicatorreticle,RuleOfThirdsGrid,ViewfinderTitleChip,TorchChip),ShutterButton/RecordButton/CameraControlsBar/ScrimIconButton,ValueSlider/ZoomControls,CapturedImagePreview/CapturedVideoPreview/VideoPlayer, theSettingsOverlaymenu, and the loading / error / unsupported state views. It re-exports:core-cameraand:core-theme.
A sample is registered in one place — a SampleCatalogItem in
SampleCatalog.kt — and the
app's NavHost is derived from that list automatically.
Use the generator, which scaffolds a working (preview-only) compose-first module and wires it into the build and catalog:
./gradlew createSample \
-PsampleName="camera2-flash" \
-PscreenName="Camera2FlashScreen" \
-Ptitle="Camera2 • Flash" \
-Pdesc="Toggle the flash with Camera2" \
-Ptype="camera2" # camera2 (default) or camerax
./gradlew spotlessApply # format the generated filesThen implement the feature in the generated Controller / Screen and re-sync Gradle.
The project is formatted with Spotless (ktlint + Apache
license headers). Run ./gradlew spotlessApply before committing.

