安卓相机2对焦状态卡住了

9

我需要在我的应用中使用Camera2 API。(Api21+) 我找到了下面的示例: https://github.com/googlesamples/android-Camera2Basic

我下载并在我的手机上启动它。当我按下“Picture”按钮时,它会调用takePhoto方法。

private void takePicture() {
    lockFocus();
}

这是一个状态机。有时这个机器会卡在STATE_WAITING_LOCK这个状态上。 我的设备正在等待对焦,但什么都没有发生!(是的,我的设备支持自动对焦)

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;
    }

这个问题有什么好的解决方案吗?而且这个程序有时会在这里崩溃:
private void unlockFocus() {
    try {
        // Reset the auto-focus trigger
        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
                CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
        setAutoFlash(mPreviewRequestBuilder);
/*HERE*/ mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
                mBackgroundHandler);
        // After this, the camera will go back to the normal state of preview.
        mState = STATE_PREVIEW;
        mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback,
                mBackgroundHandler);
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}

为什么我的设备无法聚焦?

我有同样的问题。我检查了afState的值,它始终保持在CONTROL_AF_STATE_PASSIVE_FOCUSED,但无法达到CONTROL_AF_STATE_NOT_FOCUSED_LOCKED或CONTROL_AF_STATE_FOCUSED_LOCKED。 - Sira Lam
@ketom,你找到任何解决方案了吗? - Gaurav Gupta
2个回答

2

找到Lautern的答案后,我需要进行一些调整,因为它对我没有用。
由于程序有时会卡在CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED状态下,您可以尝试重新启动AF_TRIGGER:

if (afState == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) {
    restartFocus();
}

private void restartFocus(){
        try {
            mPreviewRequestBuilder.set(
                CaptureRequest.CONTROL_AF_TRIGGER,
                CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);
            mCaptureSession.capture(
                captureRequestBuilder.build(),
                captureSessionCaptureCallback,
                mBackgroundHandler);
            lockFocus();

        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

private void lockFocus() {
    try {
        mPreviewRequestBuilder.set(
            CaptureRequest.CONTROL_AF_TRIGGER,
            CaptureRequest.CONTROL_AF_TRIGGER_START);
        mState = STATE_WAIT_LOCK;
        mCaptureSession.capture(
                mPreviewRequestBuilder.build(),
                mPreviewCaptureCallback,
                mBackgroundHandler);
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}

由于实施这项技术已经有一段时间了,我不太确定为什么我必须重新启动捕获会话。但如果没有重新启动,它对我来说是无法工作的。


我遇到了同样的问题。我应该在哪里检查呢?if (afState == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) { restartFocus(); } - Arti
非常有帮助,我通过这样做解决了我的问题:如果 (afState == CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED) 重新启动对焦() , 在我的情况下相机认为它仍然处于对焦状态,但实际上并不是。 - usman nazir

2

看起来你的程序有时会卡在CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED状态下,根据文档说明,“自动对焦算法无法对焦。镜头未移动。”链接

尝试取消AF_TRIGGER并再次启动它。像这样:

 if (afState == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) {
          getRidOfNotFocusedLock();
}

并且:

private void getRidOfNotFocusedLock(){
        try {
            mPreviewRequestBuilder.set(
                    CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);
            mCaptureSession.capture(
                    captureRequestBuilder.build(), captureSessionCaptureCallback, backgroundHandler);
            mPreviewRequestBuilder.set(
                    CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_START);

        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

1
由于我遇到了与OP相同的问题,所以我很高兴找到了这个解决方案。我尝试了一下,但它没有起作用。你必须在重置CONTROL_AF_TRIGGER之后重新开始捕获。我已经相应地编辑了你的答案。 - EarlGrey
@EarlGrey 你好,你能否将你的调整作为单独的答案发布,因为它没有被这个答案接受? - Alexander Belokon
1
@Entertain 当然,希望能对你有所帮助! - EarlGrey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接