【问题标题】:Toggle Flashlight in Camera2 without Interrupting Preview在不中断预览的情况下切换 Camera2 中的手电筒
【发布时间】:2015-12-04 16:56:10
【问题描述】:

刚刚开始使用 Camera2 框架,因为它提供了对相机低级功能的更多控制。但是,我在快速打开和关闭手电筒时遇到了一些麻烦。使用旧的 Camera API,我可以通过以下方式在提供预览的同时切换闪光灯:

try
{
    android.hardware.Camera.Parameters parameters = c.getParameters();
    if (parameters.getFlashMode().equals(Camera.Parameters.FLASH_MODE_OFF))
    {
        parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
        Log.i("HeartBeatAlgorithm", "LightOn");
    }
    else if (parameters.getFlashMode().equals(Camera.Parameters.FLASH_MODE_TORCH))
    {
        parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
        Log.i("HeartBeatAlgorithm", "LightOff");
    }
    c.setParameters(parameters);
}
catch (Exception exception)
{
    c.release();
    c = null;
}

手电筒会快速打开或关闭,没有任何明显的中断。然而,对于 Camera2,似乎 flash 模式是 CaptureSession 的一个属性,这意味着需要创建一个全新的 CaptureSession 来更改 flash 模式,即:

try
{
    SurfaceTexture texture = mTextureView.getSurfaceTexture();
    assert texture != null;

    texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
    Surface surface = new Surface(texture);
    mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);

    if (mLightNowOn == true)
    {
        mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
    }
    else
    {
        mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
    }

    mPreviewRequestBuilder.addTarget(surface);
    mPreviewRequest = mPreviewRequestBuilder.build();
    mCameraDevice.createCaptureSession(Arrays.asList(surface), mSessionStateCallback, null);
}
catch (CameraAccessException e)
{
    e.printStackTrace();
}

正如开发者文档中所述,“创建会话是一项昂贵的操作,可能需要数百毫秒,因为它需要配置相机设备的内部管道并分配内存缓冲区以将图像发送到所需的目标。”确实如此,而且在切换 Flash 模式时,我的应用会出现明显的延迟。

我真的需要能够快速切换闪光模式而不会过多地中断预览。有什么办法可以解决这个问题,还是因为新的 API 管道而无法避免?

【问题讨论】:

    标签: android delay preview flashlight camera2


    【解决方案1】:

    每次都必须创建全新的捕获会话来更改 Flash 模式是不正确的。相反,您可以在现有捕获会话上创建重复预览请求,并且每次只需 setNewRepeating 请求,如下所示:

    mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH); ... mPreviewRequest = mPreviewRequestBuilder.build(); ... mCaptureSession.setRepeatingRequest(mPreviewRequest, captureCallBack, backgroundHandler);

    您可以多次重复此序列。

    【讨论】:

      【解决方案2】:

      这似乎有点老套,但 Ivan 的输入对我有用...

      如果不是很明显,变量名称应该看起来像类/接口名称。您必须在外部范围内声明它们。

      captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
      captureRequestBuilder.addTarget(surface);
      
      captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
      captureRequest = captureRequestBuilder.build();
      cameraCaptureSession.setRepeatingRequest(captureRequest, null, backgroundHandler);
      
      torchButton = findViewById(R.id.button);
      torchButton.setOnClickListener(new View.OnClickListener() {
          public void onClick(View v) {
              if(!lightOn) {
                  try {
                      captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
                      captureRequest = captureRequestBuilder.build();
                      cameraCaptureSession.setRepeatingRequest(captureRequest, null, backgroundHandler);
                      lightOn = true;
                  } catch (CameraAccessException e) {}
              }
              else if(lightOn) {
                  try {
                      captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
                      captureRequest = captureRequestBuilder.build();
                      cameraCaptureSession.setRepeatingRequest(captureRequest, null, backgroundHandler);
                      lightOn = false;
                  } catch (CameraAccessException e) {}
              }
          }
      });
      

      这样您将在关闭手电筒的情况下开始预览,但可以通过单击按钮来控制。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-09
        • 1970-01-01
        • 2022-01-01
        相关资源
        最近更新 更多