camera2拍摄的照片模糊不清

Mar*_*ini 1 android android-camera2

在三星Galaxy S7边缘设备上拍摄照片时,我遇到了不良行为.

在拍摄照片之前,我同时等待对焦和曝光,但最后我与原生相机应用程序输出相比,有一种模糊的图像.

该问题在缩放图像上尤其明显,但在未缩放时也存在.我也试图启用光学图像稳定,但问题并没有解决.

下面是解释问题的链接示例图像.

原生相机图像

我的相机图片

这是代码:

图片捕获步骤1的方法:

public void capturePicture() {
    CameraState state = getState();
    if (state != IDLE && state != CLOSING && state != TAKE_PICTURE) {
            boolean af = false;
            boolean ae = false;
            if (isAFEnabled()) {
                af = true;
            } else if (isAEEnabled()) {
                ae = true;
            }

            if (!af && !ae) {
                takePicture();
            } else {
                triggerFocusAndExposure(true);
            }
    }

    return;
}
Run Code Online (Sandbox Code Playgroud)

触发焦点和曝光的方法:

private void triggerFocusAndExposure(boolean picture) {
    setState(WAIT_PRECAPTURE_PICTURE);

    if (isAFEnabled()) {
        previewBuilder.set(CONTROL_AF_TRIGGER, CONTROL_AF_TRIGGER_START);
    }

    if (isAEEnabled()) {
        previewBuilder.set(CONTROL_AE_PRECAPTURE_TRIGGER, CONTROL_AE_PRECAPTURE_TRIGGER_START);
    }

    try {
        cameraSession.capture(previewBuilder.build(), new SCameraCaptureSession.CaptureCallback() {
            @Override public void onCaptureCompleted(SCameraCaptureSession session, SCaptureRequest request, STotalCaptureResult result) {
                setState(PRECAPTURE_TRIGGERED_PICTURE);
            }
        }, backgroundHandler);
    } catch (CameraAccessException e) {
        return;
    }

    try {
        previewBuilder.set(CONTROL_AF_TRIGGER, CONTROL_AF_TRIGGER_IDLE);
        previewBuilder.set(CONTROL_AE_PRECAPTURE_TRIGGER, CONTROL_AE_PRECAPTURE_TRIGGER_IDLE);
        cameraSession.setRepeatingRequest(previewBuilder.build(), mSessionCaptureCallback, backgroundHandler);
    } catch (CameraAccessException e) {
    }
}
Run Code Online (Sandbox Code Playgroud)

等待焦点和曝光的方法:

private void waitPrecapture(STotalCaptureResult result, boolean picture) {
    // Check if AF/AE triggered and/or finished
    if ((!isAFTriggered(result) || isAfFinished(result)) && (!isAETriggered(result) || isAEFinished(result))) {
        takePicture();
    }
}

private boolean isAFTriggered(STotalCaptureResult result) {
    Integer afMode = result.get(SCaptureResult.CONTROL_AF_MODE);
    return afMode != CONTROL_AF_MODE_OFF &&
            afMode != CONTROL_AF_MODE_EDOF;
}

private boolean isAfFinished(STotalCaptureResult result) {
    int afState = result.get(SCaptureResult.CONTROL_AF_STATE);
    return afState == CONTROL_AF_STATE_FOCUSED_LOCKED || afState == CONTROL_AF_STATE_NOT_FOCUSED_LOCKED
            || afState == CONTROL_AF_STATE_PASSIVE_FOCUSED || afState == CONTROL_AF_STATE_PASSIVE_UNFOCUSED;
}

private boolean isAETriggered(STotalCaptureResult result) {
    boolean aeMode = result.get(SCaptureResult.CONTROL_AE_MODE) != SCaptureResult.CONTROL_AE_MODE_OFF;
    return aeMode && cameraCharacteristics.get(SCameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL)
            != SCameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY;
}

private boolean isAEFinished(STotalCaptureResult result) {
    Integer aeState = result.get(SCaptureResult.CONTROL_AE_STATE);
    return aeState == null || aeState == SCaptureResult.CONTROL_AE_STATE_CONVERGED || aeState == SCaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED
            || aeState == SCaptureResult.CONTROL_AE_STATE_LOCKED;
}
Run Code Online (Sandbox Code Playgroud)

图片捕获方法步骤2:

public void takePicture(){
    imageReader.setOnImageAvailableListener(reader -> {
        Image image = reader.acquireLatestImage();
        ByteBuffer buffer = image.getPlanes()[0].getBuffer();
        byte[] bytes = new byte[buffer.remaining()];
        buffer.get(bytes);
        image.close();
        singleSubscriber.onSuccess(bytes);
    }, imageSavingHandler);

    try {
        cameraSession.capture(captureBuilder.build(), new SCameraCaptureSession.CaptureCallback() {
             @Override
             public void onCaptureCompleted(SCameraCaptureSession session, SCaptureRequest request, STotalCaptureResult result) {
                 if (getState() == CameraState.CLOSING) {
                     return;
                 }
                 cancelAF();
             }

             @Override
             public void onCaptureStarted(SCameraCaptureSession session, SCaptureRequest request, long timestamp, long frameNumber) {
                 super.onCaptureStarted(session, request, timestamp, frameNumber);
                 shutterCallback.call();
             }    

             @Override public void onCaptureFailed(SCameraCaptureSession session, SCaptureRequest request, SCaptureFailure failure) {
                  singleSubscriber.onError(new RuntimeException("Error taking picture, onCaptureFailed"));
                  if (getState() == CameraState.CLOSING) {
                      return;
                  }
                  cancelAF();
             }
         }, backgroundHandler);

         setState(CameraState.TAKE_PICTURE);
     } catch (CameraAccessException e) {
         singleSubscriber.onError(new RuntimeException("Error capturing image", e));
     }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ini 8

我找到了解决办法. captureBuilder自动设置CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITY,CaptureRequest.EDGE_MODE_HIGH_QUALITY但在我的情况下,设备有一些问题处理这些选项.设置CaptureRequest.NOISE_REDUCTION_MODE_FASTCaptureRequest.EDGE_MODE_FAST修复问题.