如何使用Android Camera2 API捕获单个图像?
我正在使用Android Camera2 API来捕获和处理图像。图像处理是对成功捕获的响应。我遇到的问题是相机捕获了2幅图像,我无法更改Camera2基本示例中的代码,以确保只捕获一幅图像。可以通过将日志代码添加到如何使用Android Camera2 API捕获单个图像?,android,Android,我正在使用Android Camera2 API来捕获和处理图像。图像处理是对成功捕获的响应。我遇到的问题是相机捕获了2幅图像,我无法更改Camera2基本示例中的代码,以确保只捕获一幅图像。可以通过将日志代码添加到Camera2BasicFragment.java public void run() { Log.d("Camera2", "Saving image"); ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
Camera2BasicFragment.java
public void run() {
Log.d("Camera2", "Saving image");
ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
...
}
编辑-进一步调查后,问题似乎出现在示例的实现中,而不是API的任何基本问题。在示例中,以下代码跟踪摄影机的状态更改
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: {
int afState = result.get(CaptureResult.CONTROL_AF_STATE);
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_WAITING_NON_PRECAPTURE;
/** CAPTURE 1 */
captureStillPicture();
} else {
runPrecaptureSequence();
}
}
break;
}
case STATE_WAITING_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;
/** CAPTURE 2 **/
captureStillPicture();
}
break;
}
}
}
我已经验证了captureStillPicture
的两个调用都会生成图像,并因此进行处理。我不完全确定正确的状态转换应该是什么
自从我开始阅读并深入研究你的问题以来,我一直在使用摩托罗拉Nexus 6,我相信这就是它的工作方式。根据文件()所述: 每个请求将生成一个CaptureResult并为其生成新帧 一个或多个目标曲面 请注意,它表示“frames”。复数形式
说,我相信你应该只考虑内部的最后一个帧<代码> OnCopultEngult回调。
示例代码中确实存在冗余/错误。简单的解决方案是在将
/**CAPTURE 1*/
写入之前更改行
mState = STATE_PICTURE_TAKEN;
只有当所有设置都已正确/聚合时,才进入这种情况,因此最好启动静止捕获,就像它那样。它这么做只是没有录音而已 这是因为示例的实现。要解决此问题,只需在captureStillPicture()方法末尾调用unlock()方法- 为了以防万一,这里是解锁方法
private void unlockFocus() {
try {
// Reset the autofucos trigger
mPreviewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
mPreviewBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
// After this, the camera will go back to the normal state of preview.
mState = STATE_PREVIEW;
mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), mCaptureCallback, backgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
您为我指出了正确的方向,但它似乎出现在示例的实现中,而不是API固有的任何内容。我已经对我的问题进行了相应的编辑。看起来,当设备只支持camera2时,这种情况也会发生,而不是有限或完全支持。导致控件状态为空。
private void unlockFocus() {
try {
// Reset the autofucos trigger
mPreviewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
mPreviewBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
// After this, the camera will go back to the normal state of preview.
mState = STATE_PREVIEW;
mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), mCaptureCallback, backgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}