After the camera is working, I want to take a photo and get that photo as a bitmap. While it works on Android, I get the following error on iOS: *** Terminating app due to uncaught exception 'CMPViewControllerMisuse', reason: 'CMPViewController shouldn't be reused after completely removed from hierarchy, because it's logically marked as Destroyed. 'You must create a new CMPViewController and use it instead.' I didn't understand what I should do My codes are as follows:
@Composable
actual fun rememberCameraManager(onResult: (SharedImage?) -> Unit): CameraManager {
return remember {
CameraManager {
val imagePicker = UIImagePickerController()
val cameraDelegate = object : NSObject(), UIImagePickerControllerDelegateProtocol,
UINavigationControllerDelegateProtocol {
override fun imagePickerController(
picker: UIImagePickerController,
didFinishPickingMediaWithInfo: Map<Any?, *>
) {
val image =
didFinishPickingMediaWithInfo.getValue(UIImagePickerControllerEditedImage) as? UIImage
?: didFinishPickingMediaWithInfo.getValue(
UIImagePickerControllerOriginalImage
) as? UIImage
onResult.invoke(SharedImage(image))
picker.dismissViewControllerAnimated(true, null)
}
}
imagePicker.setSourceType(UIImagePickerControllerSourceType.UIImagePickerControllerSourceTypeCamera)
imagePicker.setAllowsEditing(true)
imagePicker.setCameraCaptureMode(UIImagePickerControllerCameraCaptureMode.UIImagePickerControllerCameraCaptureModePhoto)
imagePicker.setDelegate(cameraDelegate)
UIApplication.sharedApplication.keyWindow?.rootViewController?.presentViewController(
imagePicker, true, null
)
}
}
}
actual class CameraManager actual constructor(
private val onLaunch: () -> Unit
) {
actual fun launch() {
onLaunch()
}
}
actual class SharedImage(private val image: UIImage?) {
@OptIn(ExperimentalForeignApi::class)
actual fun toByteArray(): ByteArray? {
return if (image != null) {
val imageData = UIImageJPEGRepresentation(image, COMPRESSION_QUALITY)
?: throw IllegalArgumentException("image data is null")
val bytes = imageData.bytes ?: throw IllegalArgumentException("image bytes is null")
val length = imageData.length
val data: CPointer<ByteVar> = bytes.reinterpret()
ByteArray(length.toInt()) { index -> data[index] }
} else {
null
}
}
actual fun toImageBitmap(): ImageBitmap? {
val byteArray = toByteArray()
return if (byteArray != null) {
Image.makeFromEncoded(byteArray).toComposeImageBitmap()
} else {
null
}
}
private companion object {
const val COMPRESSION_QUALITY = 0.99
}
}
@Composable
fun FaceRecognitionScene(onComplete :() -> Unit) {
var imageBitmap by remember { mutableStateOf<ImageBitmap?>(null) }
var launchCamera by remember { mutableStateOf(value = false) }
val cameraManager = rememberCameraManager {
coroutineScope.launch {
val bitmap =
it?.toImageBitmap()
imageBitmap = bitmap
}
}
if (launchCamera) {
viewModel.onRequestPermissionButtonPressed()
if (viewModel.isPermissionGranted) {
cameraManager.launch()
}
launchCamera = false
}
}