Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/kashif-e/camerak
A camera library for Compose Multiplatform
https://github.com/kashif-e/camerak
android-library camerax compose-multiplatform compose-ui hacktoberfest kotlin-android kotlin-multiplatform
Last synced: 6 days ago
JSON representation
A camera library for Compose Multiplatform
- Host: GitHub
- URL: https://github.com/kashif-e/camerak
- Owner: Kashif-E
- License: mit
- Created: 2024-09-14T17:36:19.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2025-01-16T08:42:36.000Z (16 days ago)
- Last Synced: 2025-01-19T09:04:42.357Z (13 days ago)
- Topics: android-library, camerax, compose-multiplatform, compose-ui, hacktoberfest, kotlin-android, kotlin-multiplatform
- Language: Kotlin
- Homepage:
- Size: 355 KB
- Stars: 185
- Watchers: 2
- Forks: 12
- Open Issues: 1
-
Metadata Files:
- Readme: README.MD
- License: LICENSE
Awesome Lists containing this project
README
# CameraK Library
## Overview
The **CameraK Library** is a camera solution designed for Compose Multiplatform, currently
supporting both **Android** and **iOS**. While there are plans to expand support to additional
platforms, this will take time.CameraK offers features such as **Camera Preview**, **Image Capture**, **Saving Images Locally**,
and **Exposing Images as ByteArrays**. It has a plugin-based API that allows developers to extend
and enhance its functionality. Currently, two plugins are available: one for saving images and
another for scanning QR codes.***Like What you see?***
**Buy me a coffee**
## Installation
```Kotlin
implementation("io.github.kashif-mehmood-km:camerak:+")
```if you want to save images to device add the plugin:
```Kotlin
implementation("io.github.kashif-mehmood-km:image_saver_plugin:0.0.2")
````if you want to add QR scanning capability then you need the QR scanner plugin:
```Kotlin
implementation("io.github.kashif-mehmood-km:qr_scanner_plugin:0.0.3")
```## Supported Platforms
- Android
- IOS
- More will be added later## Usage
This is a simple example of how to use the CameraK library in your app.
#### Permissions
Add the following permissions to your `AndroidManifest.xml` file:
```xml
```Add the following to your info.plist file for iOS
```xml
NSCameraUsageDescriptionCamera permission is required for the app to work.
NSPhotoLibraryUsageDescriptionPhoto Library permission is required for
the app to work.
```Checking for permission and asking if needed
```Kotlin
// Initialize Camera Permission State based on current permission status
val cameraPermissionState = remember {
mutableStateOf(
permissions.hasCameraPermission()
)
}// Initialize Storage Permission State
val storagePermissionState = remember {
mutableStateOf(
permissions.hasStoragePermission()
)
}if (!cameraPermissionState.value) {
permissions.RequestCameraPermission(onGranted = { cameraPermissionState.value = true },
onDenied = {
println("Camera Permission Denied")
})
}if (!storagePermissionState.value) {
permissions.RequestStoragePermission(onGranted = { storagePermissionState.value = true },
onDenied = {
println("Storage Permission Denied")
})
}// Initialize CameraController only when permissions are granted
if (cameraPermissionState.value && storagePermissionState.value) {
}```
If permissions are granted we first create a camera controller
```Kotlin
val cameraController = remember { mutableStateOf(null) }
```After this if needed, create plugins
```Kotlin
val imageSaverPlugin = rememberImageSaverPlugin(
config = ImageSaverConfig(
isAutoSave = false, // Set to true to enable automatic saving
prefix = "MyApp", // Prefix for image names when auto-saving
directory = Directory.PICTURES, // Directory to save images
customFolderName = "CustomFolder" // Custom folder name within the directory, only works on android for now
)
)
val qrScannerPlugin = rememberQRScannerPlugin(coroutineScope = coroutineScope)LaunchedEffect(Unit) {
qrScannerPlugin.getQrCodeFlow().distinctUntilChanged()
.collectLatest { qrCode ->
println("QR Code Detected flow: $qrCode")
snackbarHostState.showSnackbar("QR Code Detected flow: $qrCode")
qrScannerPlugin.pauseScanning()
}
}
```After this we can create a Camera Preview and pass camera configuration, the it will create a
`CameraController` and we can get it from the `onCameraControllerReady` callback. Once we get the
controller we can then show the camera screen.```Kotlin
CameraPreview(modifier = Modifier.fillMaxSize(), cameraConfiguration = {
setCameraLens(CameraLens.BACK)
setFlashMode(FlashMode.OFF)
setImageFormat(ImageFormat.JPEG)
setDirectory(Directory.PICTURES)
addPlugin(imageSaverPlugin)
addPlugin(qrScannerPlugin)
}, onCameraControllerReady = {
cameraController.value = it
println("Camera Controller Ready ${cameraController.value}")
qrScannerPlugin.startScanning()
})
cameraController.value?.let { controller ->
CameraScreen(cameraController = controller, imageSaverPlugin)
}
```Here is a sample camera screen that is in the `Sample` module
```Kotlin
@OptIn(ExperimentalResourceApi::class, ExperimentalUuidApi::class)
@Composable
fun CameraScreen(cameraController: CameraController, imageSaverPlugin: ImageSaverPlugin) {
val scope = rememberCoroutineScope()
var imageBitmap by remember { mutableStateOf(null) }
var isFlashOn by remember { mutableStateOf(false) }Box(
modifier = Modifier.fillMaxSize()
) {Row(
modifier = Modifier.fillMaxWidth().padding(16.dp).align(Alignment.TopStart),
horizontalArrangement = Arrangement.SpaceBetween
) {
// Flash Mode Switch
Row(verticalAlignment = Alignment.CenterVertically) {
Text(text = "Flash")
Spacer(modifier = Modifier.width(8.dp))
Switch(checked = isFlashOn, onCheckedChange = {
isFlashOn = it
cameraController.toggleFlashMode()
})
}// Camera Lens Toggle Button
Button(onClick = { cameraController.toggleCameraLens() }) {
Text(text = "Toggle Lens")
}
}
// Capture Button at the Bottom Center
Button(
onClick = {
scope.launch {
when (val result = cameraController.takePicture()) {
is ImageCaptureResult.Success -> {imageBitmap = result.byteArray.decodeToImageBitmap()
// If auto-save is disabled, manually save the image
if (!imageSaverPlugin.config.isAutoSave) {
// Generate a custom name or use default
val customName = "Manual_${Uuid.random().toHexString()}"imageSaverPlugin.saveImage(
byteArray = result.byteArray, imageName = customName
)
}
}is ImageCaptureResult.Error -> {
println("Image Capture Error: ${result.exception.message}")
}
}
}
}, modifier = Modifier.size(70.dp).clip(CircleShape).align(Alignment.BottomCenter)) {
Text(text = "Capture")
}// Display the captured image
imageBitmap?.let { bitmap ->
Image(
bitmap = bitmap,
contentDescription = "Captured Image",
modifier = Modifier.fillMaxSize().padding(16.dp)
)LaunchedEffect(bitmap) {
delay(3000)
imageBitmap = null
}
}
}
}
```You can check the `Sample` for more details.
The library is in an experimental stage, APIs can change/break.
### Plugin API
CameraK has a plugin api which can be used by devs to enhance the capabilities of the library for their own needs, The design for it is not final but you can check `qrScannerPlugin` or `imageSaverPlugin` to check how you can build your own plugins.
**Contributions**
We welcome contributions! Before submitting a pull request, please open an issue so we can discuss
the proposed changes and collaborate on improving the project.**Feature Requests**
Feature requests are encouraged, and I’ll do my best to address them as quickly as possible.## License
```
MIT License
```