Skip to content

Commit

Permalink
Add captureMode parameter to PeekabooCamera composable for camera pos…
Browse files Browse the repository at this point in the history
…ition control
  • Loading branch information
onseok committed Dec 15, 2023
1 parent cee3d06 commit fde0511
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ private val executor = Executors.newSingleThreadExecutor()
@Composable
actual fun PeekabooCamera(
modifier: Modifier,
cameraMode: CameraMode,
onCapture: (byteArray: ByteArray?) -> Unit,
) {
val cameraPermissionState =
Expand All @@ -58,7 +59,7 @@ actual fun PeekabooCamera(
)
when (cameraPermissionState.status) {
PermissionStatus.Granted -> {
CameraWithGrantedPermission(modifier, onCapture)
CameraWithGrantedPermission(modifier, cameraMode, onCapture)
}
is PermissionStatus.Denied -> {
LaunchedEffect(Unit) {
Expand All @@ -72,6 +73,7 @@ actual fun PeekabooCamera(
@Composable
private fun CameraWithGrantedPermission(
modifier: Modifier,
cameraMode: CameraMode,
onCapture: (byteArray: ByteArray) -> Unit,
) {
val context = LocalContext.current
Expand All @@ -81,7 +83,14 @@ private fun CameraWithGrantedPermission(
val preview = Preview.Builder().build()
val previewView = remember { PreviewView(context) }
val imageCapture: ImageCapture = remember { ImageCapture.Builder().build() }
var isFrontCamera by rememberSaveable { mutableStateOf(false) }
var isFrontCamera by rememberSaveable {
mutableStateOf(
when (cameraMode) {
CameraMode.Front -> true
CameraMode.Back -> false
},
)
}
val cameraSelector =
remember(isFrontCamera) {
val lensFacing =
Expand Down Expand Up @@ -129,7 +138,7 @@ private fun CameraWithGrantedPermission(
modifier =
modifier
.pointerInput(isFrontCamera) {
detectHorizontalDragGestures { change, dragAmount ->
detectHorizontalDragGestures { _, dragAmount ->
if (dragAmount.absoluteValue > 50.0) {
isFrontCamera = !isFrontCamera
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.preat.peekaboo.ui

sealed class CameraMode {
data object Front : CameraMode()

data object Back : CameraMode()
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ import androidx.compose.ui.Modifier
@Composable
expect fun PeekabooCamera(
modifier: Modifier,
cameraMode: CameraMode = CameraMode.Back,
onCapture: (byteArray: ByteArray?) -> Unit,
)
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import platform.AVFoundation.AVCaptureDevice
import platform.AVFoundation.AVCaptureDeviceDiscoverySession.Companion.discoverySessionWithDeviceTypes
import platform.AVFoundation.AVCaptureDeviceInput
import platform.AVFoundation.AVCaptureDeviceInput.Companion.deviceInputWithDevice
import platform.AVFoundation.AVCaptureDevicePositionBack
import platform.AVFoundation.AVCaptureDevicePositionFront
import platform.AVFoundation.AVCaptureDeviceTypeBuiltInDualCamera
import platform.AVFoundation.AVCaptureDeviceTypeBuiltInDualWideCamera
Expand Down Expand Up @@ -96,6 +97,7 @@ private val deviceTypes =
@Composable
actual fun PeekabooCamera(
modifier: Modifier,
cameraMode: CameraMode,
onCapture: (byteArray: ByteArray?) -> Unit,
) {
var cameraAccess: CameraAccess by remember { mutableStateOf(CameraAccess.Undefined) }
Expand Down Expand Up @@ -135,21 +137,28 @@ actual fun PeekabooCamera(
}

CameraAccess.Authorized -> {
AuthorizedCamera(onCapture)
AuthorizedCamera(cameraMode, onCapture)
}
}
}
}

@Suppress("FunctionName")
@Composable
private fun BoxScope.AuthorizedCamera(onCapture: (byteArray: ByteArray?) -> Unit) {
private fun BoxScope.AuthorizedCamera(
cameraMode: CameraMode,
onCapture: (byteArray: ByteArray?) -> Unit,
) {
val camera: AVCaptureDevice? =
remember {
discoverySessionWithDeviceTypes(
deviceTypes = deviceTypes,
mediaType = AVMediaTypeVideo,
position = AVCaptureDevicePositionFront,
position =
when (cameraMode) {
CameraMode.Front -> AVCaptureDevicePositionFront
CameraMode.Back -> AVCaptureDevicePositionBack
},
).devices.firstOrNull() as? AVCaptureDevice
}
if (camera != null) {
Expand Down Expand Up @@ -191,7 +200,11 @@ private fun BoxScope.RealDeviceCamera(
if (photoData != null) {
var uiImage = UIImage(photoData)
if (uiImage.imageOrientation != UIImageOrientation.UIImageOrientationUp) {
UIGraphicsBeginImageContextWithOptions(uiImage.size, false, uiImage.scale)
UIGraphicsBeginImageContextWithOptions(
uiImage.size,
false,
uiImage.scale,
)
uiImage.drawInRect(
CGRectMake(
x = 0.0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import com.preat.peekaboo.image.picker.SelectionMode
import com.preat.peekaboo.image.picker.rememberImagePickerLauncher
import com.preat.peekaboo.image.picker.toImageBitmap
import com.preat.peekaboo.ui.BackButton
import com.preat.peekaboo.ui.CameraMode
import com.preat.peekaboo.ui.PeekabooCamera
import com.preat.peekaboo.ui.style.PeekabooTheme
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -81,13 +82,14 @@ fun App() {
if (showCamera) {
PeekabooCamera(
modifier = Modifier.fillMaxSize(),
cameraMode = CameraMode.Back,
onCapture = { byteArray ->
byteArray?.let {
images = listOf(it.toImageBitmap())
} ?: scope.launch {
snackbarHostState.showSnackbar(
message =
"Error occurred.",
"Unable to capture the image. Please try again.",
)
}
showCamera = false
Expand Down

0 comments on commit fde0511

Please sign in to comment.