camera2 API でフラッシュ画像と RAW を取り、JPEG と DNG ファイルを保存してみました。最初に撮影したとき、結果の画像 (jpeg) は黒です。セカンドショットでは、すべて問題ありません!完全に暗い部屋で写真を撮ります。両方のショットでフラッシュが発光します。そして、フラッシュが2回発光するたびに(プリキャプチャとキャプチャ)。
また、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