简体   繁体   English

Kotlin 和相机 2 中的 ImageReader - 从相机读取器表面保存.jpg 文件

[英]ImageReader in Kotlin & Camera 2 - saving .jpg file from a camera reader surface

I am trying to get a photo out of my ImageReader.surface that i have added as a target on my capture request for a CaptureSession, I am struggling on this as i have tried to use the imageReader.acquireLatestImage() but this alawys reference me to a null object wither in a new imagewriter.newInstance(...).dequeueinputimage which i use ImageReader.surface in it or when i aquire the image from the reader, it seems a problem with my imagereader surface, but i have tried so many ways and failed to figure out how to simply pull an image out of this capture with knowing that im closing my images on the reader ImageAVailablelistener:我正在尝试从我的 ImageReader.surface 中获取一张照片,该照片已添加为我的 CaptureSession 捕获请求中的目标,我正在为此苦苦挣扎,因为我尝试使用 imageReader.acquireLatestImage() 但这个 alawys 引用了我到 null object 在我使用 ImageReader.surface 的新 imagewriter.newInstance(...).dequeueinputimage 中枯萎,或者当我从阅读器获取图像时,我的图像阅读器表面似乎有问题,但我已经尝试过了有很多方法,但无法弄清楚如何在知道我关闭阅读器 ImageAVailablelistener 上的图像的情况下简单地从该捕获中提取图像:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.amjadshuk.roadanalysia, PID: 18251
java.lang.NullPointerException: Attempt to invoke virtual method 'android.media.Image$Plane[] android.media.Image.getPlanes()' on a null object reference
    at com.amjadshuk.roadanalysia.MainActivity.onCreate$lambda-14(MainActivity.kt:482)
    at com.amjadshuk.roadanalysia.MainActivity.$r8$lambda$NXtavG2wfAwvFvETtEdf5FaiLSE(Unknown Source:0)
    at com.amjadshuk.roadanalysia.MainActivity$$ExternalSyntheticLambda0.onImageAvailable(Unknown Source:2)
    at android.media.ImageReader$ListenerHandler.handleMessage(ImageReader.java:812)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:246)
    at android.app.ActivityThread.main(ActivityThread.java:8506)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1139)

My whole code:我的整个代码:

   @RequiresApi(Build.VERSION_CODES.P)
fun camera3() {


    val handlerThread = HandlerThread("",HandlerThread.NORM_PRIORITY).apply {
        start()
    }
    val handler =  HandlerCompat.createAsync(handlerThread.looper).apply {
        post {
            //-----------------------------------------------------------------

            GlobalScope.launch {
                Looper.prepare()

                val cm = getSystemService(Context.CAMERA_SERVICE) as CameraManager

                val cc: CameraDevice.StateCallback = object : CameraDevice.StateCallback() {

                    @RequiresApi(Build.VERSION_CODES.Q)
                    override fun onOpened(cm: CameraDevice) {
                        findViewById<TextView>(R.id.textView29).text = "Camera 1 opened"


                        val surface1 = findViewById<SurfaceView>(R.id.surfaceView3).holder.surface


                        val cr = cm.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE).apply {


                            addTarget(surface1)
                            addTarget(imageReader.surface)

                        }.build()

                        val outputConfiguration = OutputConfiguration(surface1)
                        val outputConfiguration2 = OutputConfiguration(imageReader.surface)
                        val out = mutableListOf(outputConfiguration, outputConfiguration2)


                        cm.createCaptureSession(
                            SessionConfiguration(SessionConfiguration.SESSION_REGULAR,
                                out,
                                mainExecutor,
                                object : CameraCaptureSession.StateCallback() {
                                    override fun onConfigured(p0: CameraCaptureSession) {


                                        p0.setRepeatingRequest(
                                            cr, object : CameraCaptureSession.CaptureCallback() {

                                                override fun onCaptureCompleted(
                                                    session: CameraCaptureSession,
                                                    request: CaptureRequest,
                                                    result: TotalCaptureResult
                                                ) {
                                                    super.onCaptureCompleted(
                                                        session,
                                                        request,
                                                        result
                                                    )





                                                    Toast.makeText(applicationContext,"capture completed",Toast.LENGTH_SHORT).show()

                                                }
                                                                                                },
                                            null
                                        )

                                    }

                                    override fun onConfigureFailed(p0: CameraCaptureSession) {

                                    }

                                })
                        )
                    }

                    override fun onDisconnected(cm: CameraDevice) {


                    }

                    override fun onError(cm: CameraDevice, p1: Int) {


                    }


                }

                if (ActivityCompat.checkSelfPermission(
                        applicationContext,
                        Manifest.permission.CAMERA
                    ) != PackageManager.PERMISSION_GRANTED
                ) {


                    this@MainActivity.requestPermissions(arrayOf(Manifest.permission.CAMERA), 9998)


                }



                if (cm.cameraIdList.isNotEmpty()) {
                    cm.getCameraCharacteristics(cm.cameraIdList.first())
                        .get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES)
                    cm.openCamera(cm.cameraIdList.first(), mainExecutor, cc)
                }

                val cameraAccessException = CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED)
                cameraAccessException.printStackTrace()
                val message = cameraAccessException.message!!
                Log.e("camera2", "camera2: ${message}", cameraAccessException.fillInStackTrace())

                Looper.loop()
            }



        }
    }
        }

OnCreate:创建时:

 imageReader.setOnImageAvailableListener({

            it.acquireLatestImage().close()
        val image = imageReader.acquireLatestImage()
      val byteArray =   image.planes.last().buffer.array()
        val file = FileOutputStream(File.createTempFile("image",".jpg",filesDir))
        file.write(byteArray)

    },null)
            it.acquireLatestImage().close()
        val image = imageReader.acquireLatestImage()

If this code is what you actually have, you're acquiring the latest available image and then immediately closing it.如果此代码是您实际拥有的,则您正在获取最新的可用图像,然后立即关闭它。 And then you try to get another image right off.然后你试着马上得到另一个图像。 It's unlikely a second image will have been produced by the camera at that point, so you'll get back null .此时相机不太可能生成第二张图像,因此您将返回null

Just remove the first acquireLatestImage line.只需删除第一个 acquireLatestImage 行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM