如何在CameraX API中夹在摄像机之间?

时间:2019-09-18 05:57:59

标签: android android-camerax

基于CameraX BasicsIntroduction to CAmeraX教程,我成功创建了一个活动,该活动在该活动中打开Camera。我想通过单击按钮在正面和背面之间切换相机。我使用以下代码来做到这一点:

@Override
protected void onCreate(Bundle savedInstanceState)
{
     ...

     cameraOrientation = CameraX.LensFacing.BACK;
     StartCamera();

     switchCamera.setOnClickListener(new View.OnClickListener()
     {
         @SuppressLint("RestrictedApi")
         @Override
         public void onClick(View view)
         {
             CameraX.unbindAll();

             cameraOrientation = (cameraOrientation == CameraX.LensFacing.BACK ? CameraX.LensFacing.FRONT : CameraX.LensFacing.BACK);
             try {
                 StartCamera();
             } catch (Exception e) {
                 Toast.makeText(context, "Error", Toast.LENGTH_SHORT).show(); }
         }
     });
 }

private void StartCamera()
{
    previewConfig = new PreviewConfig.Builder()
            .setLensFacing(cameraOrientation)
            .build();
    preview = new Preview(previewConfig);
    preview.setOnPreviewOutputUpdateListener(
            new Preview.OnPreviewOutputUpdateListener()
            {
                @Override
                public void onUpdated(Preview.PreviewOutput previewOutput)
                {
                    textureView.setSurfaceTexture(previewOutput.getSurfaceTexture());
                }
            });

    imageCaptureConfig = new ImageCaptureConfig.Builder()
            .setLensFacing(cameraOrientation)
            .setFlashMode(flashMode)
            .build();
    imageCapture = new ImageCapture(imageCaptureConfig);

    CameraX.bindToLifecycle(SampleCameraActivity.this, imageCapture, preview);
}

但是,当我单击按钮时,应用程序卡住了(但它没有崩溃),并且此错误不断重复显示在日志上:

E/GLConsumer: [SurfaceTexture-0–6996–1] updateAndRelease: GLConsumer is not attached to an OpenGL ES context

我还切换了闪光模式并使用此api拍照,所有这些工作正常。我也在多种设备上进行了测试。所有这些设备中都存在相同的错误。

2 个答案:

答案 0 :(得分:0)

几天前,我遇到了同样的问题,一个similar issue存在,但是建议的解决方案对我不起作用。起作用的是稍微修改了official sample中的方法bindCameraUseCases()(在类似的问题中已链接到该方法)。从startCamera()致电onCreate()

private fun startCamera() {
    texture.post { bindCameraUseCases() }
    //btn_take_picture.setOnClickListener { takePhoto() } 
    btn_swap_camera.setOnClickListener {swapCamera()}
}

@SuppressLint("RestrictedApi")
private fun swapCamera() {
    lensFacing = when (lensFacing) {
        CameraX.LensFacing.BACK -> CameraX.LensFacing.FRONT
        CameraX.LensFacing.FRONT -> CameraX.LensFacing.BACK
        else -> CameraX.LensFacing.BACK
    }
    CameraX.getCameraWithLensFacing(lensFacing)
    bindCameraUseCases()
}

// Slightly modified code from the sample
private fun bindCameraUseCases() {
    CameraX.unbindAll()

    val metrics = DisplayMetrics().also { texture.display.getRealMetrics(it) }
    val screenAspectRatio = Rational(metrics.widthPixels, metrics.heightPixels)

    val viewFinderConfig = PreviewConfig.Builder().apply {
        setLensFacing(lensFacing)
        setTargetAspectRatio(screenAspectRatio)
        setTargetRotation(texture.display.rotation)
    }.build()

    preview = AutoFitPreviewBuilder.build(viewFinderConfig, texture) // See note below

    val imageCaptureConfig = ImageCaptureConfig.Builder().apply {
        setLensFacing(lensFacing)
        setCaptureMode(ImageCapture.CaptureMode.MIN_LATENCY)
        setTargetAspectRatio(screenAspectRatio)
        setTargetRotation(texture.display.rotation)
    }.build()

    imageCapture = ImageCapture(imageCaptureConfig)

    CameraX.bindToLifecycle(this, preview, imageCapture)
}

请注意,类AutoFitPreviewBuilder来自示例,可以找到here (示例是Google许可的Apache 2.0,因此用法应合理)

答案 1 :(得分:0)

只需查找imageCapture对象并添加 .setFlashMode(FlashMode.ON)为其功能,例如

private fun createCaptureUseCase(): ImageCapture {
    val imageCaptureConfig = ImageCaptureConfig.Builder()
            //when capturaing turn on flash
        .setFlashMode(FlashMode.ON)
            //set LensFacing and rotation
        .apply {
            setLensFacing(lensFacing)
            setTargetRotation(previewView.display.rotation)
            setCaptureMode(ImageCapture.CaptureMode.MAX_QUALITY)
        }