react-native-camera-kit icon indicating copy to clipboard operation
react-native-camera-kit copied to clipboard

[android] capture is slow

Open thiagomachado1998 opened this issue 1 year ago • 0 comments

i need the photos to be captured as quickly as possible when i click the shutter, but with this library when i click the shutter the image is captured with a delay of 400ms - 900ms, this seems small but in the context of my app i need the photos to be captured as quickly as possible without any delay, could someone help me with this? i have already changed several parts of the source code, i managed to improve the time but i still haven't managed to solve this issue of the capture delay completely. but first of all I would like to thank the maintainers of this library it works perfectly for me but I need this small detail

here are the main changes I made to the camera file for android ;

react native camera kit/android/java/ckcamerakt <folder

  private fun bindCameraUseCases() {
    if (viewFinder.display == null) return

    val rotation = Surface.ROTATION_90 

    // CameraProvider
    val cameraProvider = cameraProvider
            ?: throw IllegalStateException("Camera initialization failed.")

    // CameraSelector
    val cameraSelector = CameraSelector.Builder().requireLensFacing(lensType).build()

    // Preview
    preview = Preview.Builder()
            // We request aspect ratio but no resolution
            .setTargetAspectRatio(AspectRatio.RATIO_4_3)
            // Set initial target rotation
            .setTargetRotation(rotation)
            .build()

    // ImageCapture
    imageCapture = ImageCapture.Builder()
        .setCaptureMode(ImageCapture.CAPTURE_MODE_ZERO_SHUTTER_LAG)
        // We request aspect ratio but no resolution to match preview config, but letting
        // CameraX optimize for whatever specific resolution best fits our use cases
        .setTargetAspectRatio(AspectRatio.RATIO_4_3)
        // Set initial target rotation, we will have to call this again if rotation changes
        // during the lifecycle of this use case
        .setTargetRotation(rotation)
        .setJpegQuality(50)
        .build()

    val useCases = mutableListOf(preview, imageCapture)

    // Must unbind the use-cases before rebinding them
    cameraProvider.unbindAll()

    try {
        // A variable number of use-cases can be passed here -
        // camera provides access to CameraControl & CameraInfo
        val newCamera = cameraProvider.bindToLifecycle(getActivity() as AppCompatActivity, cameraSelector, *useCases.toTypedArray())
        camera = newCamera

        resetZoom(newCamera)

        // Attach the viewfinder's surface provider to preview use case
        preview?.setSurfaceProvider(viewFinder.surfaceProvider)
    } catch (exc: Exception) {
        Log.e(TAG, "Use case binding failed", exc)

        val event: WritableMap = Arguments.createMap()
        event.putString("errorMessage", exc.message)
        currentContext.getJSModule(RCTEventEmitter::class.java).receiveEvent(
                id,
                "onError",
                event
        )
    }
    }
 fun capture(options: Map<String, Any>, promise: Promise) {
        // Create the output file option to store the captured image in MediaStore
        val outputPath: String = when {
            outputPath != null -> outputPath!!
            else -> {
                val out = File.createTempFile("ckcap", ".jpg", context.cacheDir)
                out.deleteOnExit()
                out.canonicalPath
            }
        }

        val outputFile = File(outputPath)
        val outputOptions = ImageCapture.OutputFileOptions
                    .Builder(outputFile)
                    .build()

        flashViewFinder()

        // Setup image capture listener which is triggered after photo has been taken
        imageCapture?.takePicture(
                outputOptions, ContextCompat.getMainExecutor(getActivity()), object : ImageCapture.OnImageSavedCallback {
            override fun onError(ex: ImageCaptureException) {
                Log.e(TAG, "CameraView: Photo capture failed: ${ex.message}", ex)
                promise.reject("E_CAPTURE_FAILED", "takePicture failed: ${ex.message}")
            }

            override fun onImageSaved(output: ImageCapture.OutputFileResults) {
                try {
                    val uri = output.savedUri ?: Uri.fromFile(outputFile)
            
                    val imageInfo = Arguments.createMap()
                    imageInfo.putString("uri", uri.toString())
                
                    promise.resolve(imageInfo)
                } catch (ex: Exception) {
                    Log.e(TAG, "Error while saving or decoding saved photo: ${ex.message}", ex)
                    promise.reject("E_ON_IMG_SAVED", "Error while reading saved photo: ${ex.message}")
                }
            }
        })
    }

I also updated cameraX to version “1.2.0”, so that I could use CAPTURE_MODE_ZERO_SHUTTER_LAG

"react-native": "0.72.6", "react-native-camera-kit": "^14.0.0-beta15",

thiagomachado1998 avatar Oct 05 '24 00:10 thiagomachado1998