我尝试使用 camera2 API 拍摄闪烁的图像和 RAW 并保存 JPEG 和 DNG 文件。当我第一次拍摄时,结果图像(jpeg)是黑色的。第二枪一切正常!我在完全黑暗的房间里拍照。两次拍摄都会闪光。并且每次闪光灯闪光两次(预捕获和捕获)。
当我尝试仅捕获 JPEG 图像(没有 RAW)并将曝光设置为 0 时,也会发生类似的问题。
这是创建捕获请求的代码:
public static void CreateRequests(final int format) throws CameraAccessException
{
final boolean isRAWCapture = (format == CameraController.RAW);
stillRequestBuilder = HALv3.getInstance().camDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
precaptureRequestBuilder = HALv3.getInstance().camDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
rawRequestBuilder = HALv3.getInstance().camDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
if (format == CameraController.YUV_RAW)
{
stillRequestBuilder.set(CaptureRequest.EDGE_MODE, CaptureRequest.EDGE_MODE_OFF);
stillRequestBuilder.set(CaptureRequest.NOISE_REDUCTION_MODE, CaptureRequest.NOISE_REDUCTION_MODE_OFF);
precaptureRequestBuilder.set(CaptureRequest.EDGE_MODE, CaptureRequest.EDGE_MODE_OFF);
precaptureRequestBuilder.set(CaptureRequest.NOISE_REDUCTION_MODE, CaptureRequest.NOISE_REDUCTION_MODE_OFF);
} else if (isRAWCapture)
{
stillRequestBuilder.set(CaptureRequest.EDGE_MODE, CaptureRequest.EDGE_MODE_HIGH_QUALITY);
stillRequestBuilder.set(CaptureRequest.NOISE_REDUCTION_MODE,
CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITY);
precaptureRequestBuilder.set(CaptureRequest.EDGE_MODE, CaptureRequest.EDGE_MODE_HIGH_QUALITY);
precaptureRequestBuilder.set(CaptureRequest.NOISE_REDUCTION_MODE,
CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITY);
rawRequestBuilder.set(CaptureRequest.EDGE_MODE, CaptureRequest.EDGE_MODE_OFF);
rawRequestBuilder.set(CaptureRequest.NOISE_REDUCTION_MODE, CaptureRequest.NOISE_REDUCTION_MODE_OFF);
} else
{
stillRequestBuilder.set(CaptureRequest.EDGE_MODE, CaptureRequest.EDGE_MODE_HIGH_QUALITY);
stillRequestBuilder.set(CaptureRequest.NOISE_REDUCTION_MODE,
CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITY);
precaptureRequestBuilder.set(CaptureRequest.EDGE_MODE, CaptureRequest.EDGE_MODE_HIGH_QUALITY);
precaptureRequestBuilder.set(CaptureRequest.NOISE_REDUCTION_MODE,
CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITY);
}
stillRequestBuilder.set(CaptureRequest.TONEMAP_MODE, CaptureRequest.TONEMAP_MODE_HIGH_QUALITY);
precaptureRequestBuilder.set(CaptureRequest.TONEMAP_MODE, CaptureRequest.TONEMAP_MODE_HIGH_QUALITY);
if (isRAWCapture)
rawRequestBuilder.set(CaptureRequest.TONEMAP_MODE, CaptureRequest.TONEMAP_MODE_HIGH_QUALITY);
if ((zoomLevel > 1.0f) && (format != CameraController.YUV_RAW))
{
zoomCropCapture = getZoomRect(zoomLevel, activeRect.width(), activeRect.height());
stillRequestBuilder.set(CaptureRequest.SCALER_CROP_REGION, zoomCropCapture);
precaptureRequestBuilder.set(CaptureRequest.SCALER_CROP_REGION, zoomCropCapture);
if (isRAWCapture)
rawRequestBuilder.set(CaptureRequest.SCALER_CROP_REGION, zoomCropCapture);
}
int focusMode = PreferenceManager.getDefaultSharedPreferences(MainScreen.getMainContext()).getInt(
CameraController.isFrontCamera() ? MainScreen.sRearFocusModePref : MainScreen.sFrontFocusModePref, -1);
stillRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, focusMode);
precaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, focusMode);
if (isRAWCapture)
rawRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, focusMode);
if (format == CameraController.JPEG)
{
stillRequestBuilder.addTarget(MainScreen.getJPEGImageReader().getSurface());
} else if (format == CameraController.YUV || format == CameraController.YUV_RAW)
{
stillRequestBuilder.addTarget(MainScreen.getYUVImageReader().getSurface());
} else if (format == CameraController.RAW)
{
rawRequestBuilder.addTarget(MainScreen.getRAWImageReader().getSurface());
stillRequestBuilder.addTarget(MainScreen.getJPEGImageReader().getSurface());
}
precaptureRequestBuilder.addTarget(MainScreen.getPreviewYUVImageReader().getSurface());
int flashMode = PreferenceManager.getDefaultSharedPreferences(MainScreen.getMainContext()).getInt(
MainScreen.sFlashModePref, -1);
Integer previewFlash = null;
if (flashMode == CameraParameters.FLASH_MODE_OFF) {
previewFlash = CaptureRequest.FLASH_MODE_OFF;
} else if (flashMode == CameraParameters.FLASH_MODE_SINGLE) {
previewFlash = CaptureRequest.FLASH_MODE_SINGLE;
} else if (flashMode == CameraParameters.FLASH_MODE_TORCH) {
previewFlash = CaptureRequest.FLASH_MODE_TORCH;
}
HALv3.stillRequestBuilder.set(CaptureRequest.FLASH_MODE, previewFlash);
HALv3.precaptureRequestBuilder.set(CaptureRequest.FLASH_MODE, previewFlash);
HALv3.rawRequestBuilder.set(CaptureRequest.FLASH_MODE, previewFlash);
if(flashMode == CameraParameters.FLASH_MODE_SINGLE || flashMode == CameraParameters.FLASH_MODE_AUTO || flashMode == CameraParameters.FLASH_MODE_REDEYE)
{
if(flashMode == CameraParameters.FLASH_MODE_SINGLE)
flashMode = CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH;
else if(flashMode == CameraParameters.FLASH_MODE_AUTO )
flashMode = CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH;
else
flashMode = CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE;
HALv3.stillRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
HALv3.stillRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, flashMode);
HALv3.precaptureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
HALv3.precaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, flashMode);
HALv3.rawRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
HALv3.rawRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, flashMode);
}
}
和捕获方法:
public static int captureImageWithParamsHALv3Simple(final int nFrames, final int format, final int[] pause,
final int[] evRequested, final int[] gain, final long[] exposure, final boolean resInHeap,
final boolean playShutter)
{
int requestID;
try
{
requestID = HALv3.getInstance().mCaptureSession.capture(stillRequestBuilder.build(), stillCaptureCallback,
null);
if (isRAWCapture)
HALv3.getInstance().mCaptureSession.capture(rawRequestBuilder.build(), stillCaptureCallback, null);
} catch (CameraAccessException e)
{
e.printStackTrace();
}
return 0;
}
public static int captureImageWithParamsHALv3(final int nFrames, final int format, final int[] pause,
final int[] evRequested, final int[] gain, final long[] exposure, final boolean resInHeap,
final boolean playShutter)
{
int requestID = -1;
try
{
CreateRequests(format);
precaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
requestID = HALv3.getInstance().mCaptureSession.capture(precaptureRequestBuilder.build(),
new CameraCaptureSession.CaptureCallback()
{
@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
TotalCaptureResult result)
{
precaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_IDLE);
captureImageWithParamsHALv3Simple(nFrames, format, pause, evRequested, gain, exposure,
resInHeap, playShutter);
}
}, null);
} catch (CameraAccessException e)
{
Log.e(TAG, "setting up still image capture request failed");
e.printStackTrace();
throw new RuntimeException();
}
return requestID;
}
enter code here
您也可以在这里看到项目的完整代码:https ://github.com/almalence/OpenCamera
和camera2部分: https ://github.com/almalence/OpenCamera/blob/master/src/com/almalence/opencam/cameracontroller/HALv3.java