Camera2 api:使用 imageReader 从 surfaceView 捕获图像时为空图像

问题描述 投票:0回答:0

我正在使用 Camera2 api 拍摄图像。我正在使用 imageReader 从 surfaceView 捕获图像并使用 acquireLatestImage() 来收集图像。

正在捕获图像,但如 Log.e 消息“捕获已完成”和“无法获取捕获的图像”所示,它们是空的

   private fun onCaptureButtonClick(
        captureType: String,
        imageWidth: Int,
        imageHeight: Int,
        controlMode: Int,
        cameraSettings: MutableMap<String, Any?>
    ) {


    if (captureType == "Image") {
        try {
            //CaptureRequest.Builder to configure the capture request
            val captureRequestBuilder =
                cameraDevice?.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE)
            captureRequestBuilder?.addTarget(previewSurface!!)
            captureRequestBuilder?.set(CaptureRequest.CONTROL_MODE, controlMode)

            //ImageReader to capture the image
            val imageReader = ImageReader.newInstance(imageWidth, imageHeight, ImageFormat.JPEG, 1)
            Toast.makeText(applicationContext, "Imgereader Started", Toast.LENGTH_SHORT).show()

            if (imageReader != null && cameraDevice != null) {
                // Create a CameraCaptureSession.CaptureCallback to handle capture results
                val captureCallback = object : CameraCaptureSession.CaptureCallback() {
                    override fun onCaptureCompleted(
                        session: CameraCaptureSession,
                        request: CaptureRequest,
                        result: TotalCaptureResult
                    ) {
                        Log.d(TAG, "Capture completed")
                        super.onCaptureCompleted(session, request, result)

                        //image data from the ImageReader
                        val image = imageReader.acquireLatestImage()

                        if (image != null) {
                            //image data buffer
                            val buffer = image.planes[0].buffer

                            //buffer to a ByteArray
                            val imageData = ByteArray(buffer.remaining())
                            buffer.get(imageData)

                            // Save the image data to a JPEG file
                            val outputFile = File(
                                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
                                "my_image.jpg"
                            )
                            try {
                                FileOutputStream(outputFile).use { output ->
                                    output.write(imageData)
                                }
                                Log.d(
                                    TAG,
                                    "Image saved successfully: ${outputFile.absolutePath}"
                                )

                                // Update the gallery so that the image appears in the gallery app
                                MediaScannerConnection.scanFile(
                                    applicationContext,
                                    arrayOf(outputFile.absolutePath),
                                    null,
                                    null
                                )
                            } catch (e: IOException) {
                                e.printStackTrace()
                            } finally {
                                // Close the image after saving
                                image.close()
                            }
                        } else {
                            Log.e(TAG, "Failed to acquire captured image")
                            Toast.makeText(
                                applicationContext,
                                "Failed to acquire captured image",
                                Toast.LENGTH_SHORT
                            ).show()
                        }
                        
                        updateCameraPreview()
                    }

                    override fun onCaptureFailed(
                        session: CameraCaptureSession,
                        request: CaptureRequest,
                        failure: CaptureFailure
                    ) {
                        super.onCaptureFailed(session, request, failure)
                        // Capture failed, implement your logic here
                        Log.d(TAG, "Capture failed")
                    }
                }
                //apture session with the configured capture request, imageReader surface, and capture callback
                val surfaces = mutableListOf(previewSurface, imageReader.surface)

                if (cameraCaptureSession == null) {
                    //new capture session if the current capture session is null
                    cameraDevice?.createCaptureSession(surfaces, object : CameraCaptureSession.StateCallback() {
                        override fun onConfigured(session: CameraCaptureSession) {

                            // Capture session configured successfully, get the CameraCaptureSession object
                            cameraCaptureSession = session
                            captureRequestBuilder?.build()?.let {
                                cameraCaptureSession?.capture(
                                    it, captureCallback, null
                                )
                            }
                        }
                            override fun onConfigureFailed(session: CameraCaptureSession) {
                                // Failed to configure capture session
                                Log.e(TAG, "Failed to configure capture session")
                            }
                        },
                            null
                            )
                        } else {
                        // Use the existing capture session if it's already created
                        cameraCaptureSession?.capture(
                            captureRequestBuilder!!.build(),
                            captureCallback,
                            null
                        )
                    }
                } else {
                    Log.e(TAG, "Failed to create ImageReader or CameraDevice is null")
                }
            } catch (e: CameraAccessException) {
                e.printStackTrace()
            }
        } else {
            
        }
    }

我正在通过单击按钮呼叫

btnCapture.setOnClickListener { onCaptureButtonClick(captureType, imageWidth, (aspectRatio*imageWidth),controlMode, cameraSettings) }

我已经尝试过不同的高度和宽度值。使用

获得可接受的尺寸
try {

    val cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId)

 
    val maxImageSize = cameraCharacteristics.get(
        CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP
    )?.getOutputSizes(ImageFormat.JPEG)?.maxByOrNull { it.height * it.width }

    val minImageSize = cameraCharacteristics.get(
        CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP
    )?.getOutputSizes(ImageFormat.JPEG)?.minByOrNull { it.height * it.width }

   
    if (maxImageSize != null) {
        val maxWidth = maxImageSize.width
        val maxHeight = maxImageSize.height
        Log.d(TAG, "Max Image Size: $maxWidth x $maxHeight")
    }

    if (minImageSize != null) {
        val minWidth = minImageSize.width
        val minHeight = minImageSize.height
        Log.d(TAG, "Min Image Size: $minWidth x $minHeight")
    }

} catch (e: CameraAccessException) {
    e.printStackTrace()
}

任何帮助表示赞赏。

android kotlin android-camera2 image-reader
© www.soinside.com 2019 - 2024. All rights reserved.