如何解决Android Camera2API中的“粉红色”图像捕获问题?

时间:2019-07-01 12:44:21

标签: android kotlin android-camera2

我正在尝试使用2个不同的镜头(广角镜和普通镜)捕获图像。使用Camera2API中新的多相机支持,预览可以同时在两个相机上正常运行。我正在使用华为Mate20Pro。 但是,当我捕获图片时,它仅保存粉色的JPEG图像。但是,当物体足够近时,可以完美地捕获图片。这就是我的意思。这是粉红色JPEG的外观:

enter image description here

但是,当对象足够靠近时,捕获就可以了。看起来是这样的: enter image description here

这是主要的活动代码:

 button.setOnClickListener {
            if (isRunning) {
                handler.removeCallbacksAndMessages(null)
                restartActivity()
            } else {
                button.text = "Stop"
                handler.postDelayed(object : Runnable {
                    override fun run() {
                        twoLens.reset()
                        twoLens.isTwoLensShot = true
                        MainActivity.cameraParams.get(dualCamLogicalId).let {
                            if (it?.isOpen == true) {
                                Logd("In onClick. Taking Dual Cam Photo on logical camera: $dualCamLogicalId")
                                takePicture(this@MainActivity, it)
                                Toast.makeText(applicationContext, "Captured!", Toast.LENGTH_SHORT).show()
                            }
                        }
                        handler.postDelayed(this, 1000)
                    }
                }, 2000)
            }
            isRunning = !isRunning
        }
    }

这是图片捕获代码。

fun captureStillPicture(activity: MainActivity, params: CameraParams) {
    if (!params.isOpen) {
        return
    }

    try {
        Logd("In captureStillPicture.")

        val camera = params.captureSession?.getDevice()

        if (null != camera) {
            params.captureBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE)
            params.captureBuilder?.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO)
if (params.id.equals(dualCamLogicalId) && twoLens.isTwoLensShot) {
val normalParams: CameraParams? = MainActivity.cameraParams.get(normalLensId)
val wideParams: CameraParams? = MainActivity.cameraParams.get(wideAngleId)
if (null == normalParams || null == wideParams)
        return
Logd("In captureStillPicture. This is a Dual Cam shot.")
params.captureBuilder?.addTarget(normalParams.imageReader?.surface!!)
             params.captureBuilder?.addTarget(wideParams.imageReader?.surface!!)
params.captureBuilder?.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 4)
params.captureBuilder?.set(CaptureRequest.JPEG_QUALITY, 100)
if (Build.VERSION.SDK_INT >= 28) {              params.captureBuilder?.set(CaptureRequest.DISTORTION_CORRECTION_MODE, CameraMetadata.DISTORTION_CORRECTION_MODE_OFF)
                //This is REQUIRED to disable HDR+ on Pixel 3 - even though Pixel 3 doesn't have sepia
                params.captureBuilder?.set(CaptureRequest.CONTROL_EFFECT_MODE, CameraMetadata.CONTROL_EFFECT_MODE_SEPIA)
            } else {
                //This is REQUIRED to disable HDR+ on Pixel 3 - even though Pixel 3 doesn't have sepia
                params.captureBuilder?.set(CaptureRequest.CONTROL_EFFECT_MODE, CameraMetadata.CONTROL_EFFECT_MODE_SEPIA)
                Logd("DUAL CAM DEBUG: I am setting sepia mode.")
//            Logd("DUAL CAM DEBUG: I am NOT setting sepia mode.")
            }
val rotation = activity.getWindowManager().getDefaultDisplay().getRotation()
            var capturedImageRotation = getOrientation(params, rotation)
            params.captureBuilder?.set(CaptureRequest.JPEG_ORIENTATION, capturedImageRotation)

            try {
                params.captureSession?.stopRepeating()
//                params.captureSession?.abortCaptures()
            } catch (e: CameraAccessException) {
                e.printStackTrace()
            }

            //Do the capture
            // TODO: Capture BURST HERE
if (28 <= Build.VERSION.SDK_INT)
params.captureSession?.captureSingleRequest(params.captureBuilder?.build(), params.backgroundExecutor, StillCaptureSessionCallback(activity, params))
else
params.captureSession?.capture(params.captureBuilder?.build(), StillCaptureSessionCallback(activity, params),
                    params.backgroundHandler)
        }
    } catch (e: CameraAccessException) {
        e.printStackTrace()

    } catch (e: IllegalStateException) {
        Logd("captureStillPicture IllegalStateException, aborting: " + e)
    }
}

这就是我抓取的图片的方式。

fun getImagesCaptured(activity: MainActivity, twoLens: TwoLensCoordinator){
    Logd("Normal image timestamp: " + twoLens.normalImage?.timestamp)
    Logd("Wide image timestamp: " + twoLens.wideImage?.timestamp)

    val wideBuffer: ByteBuffer? = twoLens.wideImage!!.planes[0].buffer
    val wideBytes = ByteArray(wideBuffer!!.remaining())
    wideBuffer.get(wideBytes)

    val normalBuffer: ByteBuffer? = twoLens.normalImage!!.planes[0].buffer
    val normalBytes = ByteArray(normalBuffer!!.remaining())
    normalBuffer.get(normalBytes)
    val options = BitmapFactory.Options()
    val wideMat: Mat = Mat(twoLens.wideImage!!.height, twoLens.wideImage!!.width, CvType.CV_8UC1)
    val tempWideBitmap = BitmapFactory.decodeByteArray(wideBytes, 0, wideBytes.size, options)

    val normalMat: Mat = Mat(twoLens.normalImage!!.height, twoLens.normalImage!!.width, CvType.CV_8UC1)
    val tempNormalBitmap = BitmapFactory.decodeByteArray(normalBytes, 0, normalBytes.size, options)
    save(normalBytes, "NormalShot")
    save(wideBytes, "WideShot")
}

保存功能在这里。

fun save(bytes: Bitmap, tempName: String) {
    val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
    val dataDir = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "TwoCameraImages")
    if (!dataDir.exists()) {
        dataDir.mkdir()
    }
    val fileName = tempName + "_IMG_$timeStamp.jpg"
    val fileDir = File(dataDir.path + File.separator + fileName)
    try {
        val fileOutputStream = FileOutputStream(fileDir)
        bytes.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream)
        //fileOutputStream.write(bytes)
        fileOutputStream.close()
    } catch (e: FileNotFoundException) {
        e.printStackTrace()
    } catch (e: IOException) {
        e.printStackTrace()
    }
}

我以此处提供的代码https://github.com/google/basicbokeh为基础,并切换到后置摄像头,并删除了人脸计算。但是这个粉红色的位图并没有消失。有帮助吗?

0 个答案:

没有答案