调用 Camera2 API onCaptureComplete() 但相机状态仍为 CONTROL_AE_STATE_PRECAPTURE

Posted

技术标签:

【中文标题】调用 Camera2 API onCaptureComplete() 但相机状态仍为 CONTROL_AE_STATE_PRECAPTURE【英文标题】:Camera2 API onCaptureComplete() is called but camera state is still CONTROL_AE_STATE_PRECAPTURE 【发布时间】:2016-01-02 21:17:20 【问题描述】:

我正在尝试创建一个应用,该应用使用 camera2 API 从服务中获取一些照片。

我可以让应用程序从基于Camera2Basic sample 的片段中很好地拍照。

但是当我尝试移至服务时,图像无法正确完成捕获。它永远不会超过自动曝光预捕获状态。

我将其缩小为没有预览的问题。我通过获取 Camera2Basic 代码并删除预览来组合一个测试片段,这会导致同样的问题。

我根据 Camera2Basic 示例整理了一个有问题的测试片段,我基本上只是删除了预览代码。片段代码在这里上传http://pastebin.ca/3182401。

我收到了 onCaptureCompleted() 回调,但是当我在这里检查相机自动曝光状态时,它仍处于 CONTROL_AE_STATE_PRECAPTURE 状态。

如果其中一个相机状态仍处于预捕获状态,则捕获完成对我来说没有任何意义。

有人知道这里会发生什么吗?

【问题讨论】:

有没有可能在你拍完照片后,相机会回到预拍摄状态,为下一张照片做准备? 不应该这样。文档说它应该锁定在 CONVERGED 或 FLASH_REQUIRED 状态。然后保持锁定,直到拍照或应用程序提交一个带有 android.control.aeLock == true 的请求,然后是一个带有 android.control.aeLock == false 的请求developer.android.com/reference/android/hardware/camera2/… 我得到CONTROL_AE_STATE 始终为空。知道为什么吗?我正在使用相同的样本。并在多台设备上试用。 【参考方案1】:

文档中没有提到,但 onCaptureCompleted 实际上是在发送请求时调用的,而不是在预捕获或自动对焦序列完成时调用。 Camera2Basic 依赖于不断运行的预览,因为预览充当相机状态的恒定监视器。没有它,您将无法知道预捕获序列何时真正结束。

【讨论】:

【参考方案2】:

我认为您将 mState 设置为预捕获状态的逻辑存在缺陷

private void process(CaptureResult result) 
        switch (mState) 
            case STATE_PREVIEW: 
                // We have nothing to do when the camera preview is working normally.
                break;
            
            case STATE_WAITING_LOCK: 
                Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
                if (afState == null) 
                    captureStillPicture();
                 else if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState ||
                        CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState) 
                    // CONTROL_AE_STATE can be null on some devices
                    Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
                    if (aeState == null ||
                            aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) 
                        mState = STATE_PICTURE_TAKEN;
                        captureStillPicture();
                     else 
                        runPrecaptureSequence();
                    
                
                break;
            
            case STATE_WAITING_PRECAPTURE: 
                // CONTROL_AE_STATE can be null on some devices
                Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
                if (aeState == null ||
                        aeState == CaptureResult.CONTROL_AE_STATE_PRECAPTURE ||
                        aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED) 
                    mState = STATE_WAITING_NON_PRECAPTURE;
                
                break;
            
            case STATE_WAITING_NON_PRECAPTURE: 
                // CONTROL_AE_STATE can be null on some devices
                Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
                if (aeState == null || aeState != CaptureResult.CONTROL_AE_STATE_PRECAPTURE) 
                    mState = STATE_PICTURE_TAKEN;
                    captureStillPicture();
                
                break;
            
        
    

是否会输入 case STATE_WAITING_PRECAPTURE?

【讨论】:

以上是关于调用 Camera2 API onCaptureComplete() 但相机状态仍为 CONTROL_AE_STATE_PRECAPTURE的主要内容,如果未能解决你的问题,请参考以下文章

调用需要 API 级别 21(让 camera2 在低于 21 的设备上运行?)[重复]

使用camera2 API无需预览即可捕获图片

如何使用Android中的Camera2 API在不预览的情况下拍摄多张照片?

Camera2用Android API 29中的两个物理流替换一个逻辑流

Android Camera API/Camera2 API 相机预览及滤镜贴纸等处理

Android Camera API/Camera2 API 相机预览及滤镜贴纸等处理