1

基于CameraX 基础知识CAmeraX教程简介,我成功创建了一个在该 Activity 中打开 Camera 的 Activity。我想通过单击按钮在前后切换相机。我使用以下代码来做到这一点:

@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 切换闪光灯模式并拍照,所有这些都可以正常工作。我也在多种设备上进行了测试。所有这些设备中的相同错误。

4

2 回答 2

1

几天前我遇到了同样的问题,存在类似的问题,但建议的解决方案对我不起作用。有效的是稍微修改官方示例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来自示例,可以在此处找到 (示例是由 Google 授权的 Apache 2.0,因此使用应该是公平的)

于 2019-09-20T12:23:53.400 回答
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)
        }
于 2020-07-16T14:26:09.550 回答