我正在将相机应用程序从camera1迁移到camera2。我在Motorola G5和Samsung Galaxy S4上遇到了一个奇怪的问题,它们的闪光灯模式处于开启状态,每次我点击预览视图进行手动对焦时,闪光灯都会闪光。
有人遇到同样的问题吗? 这是我用于点击聚焦功能的代码:
val focusAreaTouch = calculateFocusArea(pointOfInterestX, pointOfInterestY, sensorArraySize)
//cancel any existing AF trigger
previewRequestBuilder?.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL)
previewRequestBuilder?.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF)
try {
captureSession?.capture(previewRequestBuilder?.build(), captureCallback, null)
}catch (ex: Exception) {
Log.e(TAG, "Tap To Focus -> Failed to cancel any existing AF trigger.", ex)
}
Log.e(TAG, "AF Regions: " + previewRequestBuilder?.get(CaptureRequest.CONTROL_AF_REGIONS)?.first()?.rect)
//Then we add a new AF trigger with focus region
previewRequestBuilder?.set(CaptureRequest.CONTROL_AF_REGIONS, arrayOf(focusAreaTouch))
previewRequestBuilder?.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO)
previewRequestBuilder?.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO)
previewRequestBuilder?.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START)
这是我检查AE状态的方法:
private fun process(result: CaptureResult) {
when (state) {
CameraState.STATE_LOCKING -> {
val af = result.get(CaptureResult.CONTROL_AF_STATE) ?: return
if (af == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED
|| af == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED
|| af == CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED) {
val ae = result.get(CaptureResult.CONTROL_AE_STATE)
if (ae == null || ae == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
state = CameraState.STATE_CAPTURING
onReady()
} else {
state = CameraState.STATE_LOCKED
onPreCaptureRequired()
}
}
}
CameraState.STATE_PRECAPTURE -> {
val ae = result.get(CaptureResult.CONTROL_AE_STATE)
if (ae == null || ae == CaptureResult.CONTROL_AE_STATE_PRECAPTURE ||
ae == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED ||
ae == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
state = CameraState.STATE_WAITING
}
}
CameraState.STATE_WAITING -> {
val ae = result.get(CaptureResult.CONTROL_AE_STATE)
if (ae == null || ae != CaptureResult.CONTROL_AE_STATE_PRECAPTURE) {
state = CameraState.STATE_CAPTURING
onReady()
}
}
}
}
答案 0 :(得分:1)
原因是如果您还设置了自动曝光,则自动曝光算法会根据需要根据当前的光照条件适当地调整曝光,从而触发闪光灯。
要解决此问题,请为预览和照片捕获会话分别处理Flash配置。使用下一个功能配置您的请求构建器。
调用 setFlash()时有4个地方。请注意,该方法仅设置给定的构建器Flash配置,您仍然需要将构建器传递给目标会话。对于预览会话,将作为重复请求。
static final int FLASH_MODE_OFF = 0;
static final int FLASH_MODE_AUTO = 1;
static final int FLASH_MODE_ON = 2;
static final int FLASH_MODE_TORCH = 3;
public void setFlash(@NonNull final CaptureRequest.Builder builder,
final boolean isPreviewSession, final int flashMode)
{
if (isPreviewSession == true)
{
// For preview session
builder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON);
if (flashMode == FLASH_MODE_TORCH)
{
builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH);
}
else
{
builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF);
}
}
else
{
// For capture session
if (flashMode == FLASH_MODE_OFF)
{
builder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON);
builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF);
}
else if (flashMode == FLASH_MODE_AUTO)
{
builder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH);
builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF);
}
else if (flashMode == FLASH_MODE_ON)
{
builder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON_ALWAYS_FLASH);
builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_SINGLE);
}
else if (flashMode == FLASH_MODE_TORCH)
{
builder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON);
builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH);
}
}
}