camera2拍摄的照片模糊 [英] camera2 pictures taken are blurred
问题描述
在Samsung Galaxy S7边缘设备上拍摄照片时,我遇到不良行为.
I'm experiencing a bad behavior when capturing a photo on a Samsung Galaxy S7 edge device.
在拍照之前,我同时等待对焦和曝光,但是最后,与本地相机应用程序的输出相比,我有一种模糊的图像.
I wait simultaneously for focus and exposure before taking the picture but at the end I have a kind of blurred image compared to the native camera app output.
该问题在缩放的图像上尤其明显,但在未缩放时也存在.我还尝试启用光学图像稳定功能,但问题并未解决.
The problem is especially visible on zoomed images but is present also when not zoomed. I've also tried to enable the optical image stabilization but the problem isn't fixed.
下面是说明问题的链接示例图像.
Below are linked sample images explaining the problem.
这是代码:
图片捕获方法第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;
}
触发焦点和曝光的方法:
Method for triggering focus and exposure:
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) {
}
}
等待焦点和曝光的方法:
Methods for waiting focus and exposure:
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;
}
图片捕获方法第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));
}
}
推荐答案
我已经找到了解决方法.
captureBuilder
自动设置CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITY
和CaptureRequest.EDGE_MODE_HIGH_QUALITY
,但就我而言,设备在处理这些选项时遇到一些问题.设置CaptureRequest.NOISE_REDUCTION_MODE_FAST
和CaptureRequest.EDGE_MODE_FAST
可以解决此问题.
I've found the fix.
captureBuilder
automatically sets CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITY
and CaptureRequest.EDGE_MODE_HIGH_QUALITY
but in my case the device has some problem handling these options. Setting CaptureRequest.NOISE_REDUCTION_MODE_FAST
and CaptureRequest.EDGE_MODE_FAST
fixes the problem.
这篇关于camera2拍摄的照片模糊的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!