|
@@ -9,6 +9,7 @@ import androidx.camera.core.Camera
|
|
|
import androidx.camera.core.CameraSelector
|
|
import androidx.camera.core.CameraSelector
|
|
|
import androidx.camera.core.ImageCapture
|
|
import androidx.camera.core.ImageCapture
|
|
|
import androidx.camera.core.ImageCaptureException
|
|
import androidx.camera.core.ImageCaptureException
|
|
|
|
|
+import androidx.camera.core.FocusMeteringAction
|
|
|
import androidx.camera.core.Preview
|
|
import androidx.camera.core.Preview
|
|
|
import androidx.camera.lifecycle.ProcessCameraProvider
|
|
import androidx.camera.lifecycle.ProcessCameraProvider
|
|
|
import androidx.camera.camera2.interop.Camera2CameraControl
|
|
import androidx.camera.camera2.interop.Camera2CameraControl
|
|
@@ -31,6 +32,7 @@ import com.joe.camera.webcam.model.CameraState
|
|
|
import java.util.concurrent.Executor
|
|
import java.util.concurrent.Executor
|
|
|
import java.util.concurrent.Executors
|
|
import java.util.concurrent.Executors
|
|
|
import java.io.File
|
|
import java.io.File
|
|
|
|
|
+import java.util.concurrent.TimeUnit
|
|
|
|
|
|
|
|
class CameraController(private val context: Context, private val onState: (CameraState) -> Unit, private val onMessage: (String) -> Unit) {
|
|
class CameraController(private val context: Context, private val onState: (CameraState) -> Unit, private val onMessage: (String) -> Unit) {
|
|
|
private val executor: Executor = ContextCompat.getMainExecutor(context)
|
|
private val executor: Executor = ContextCompat.getMainExecutor(context)
|
|
@@ -70,6 +72,9 @@ class CameraController(private val context: Context, private val onState: (Camer
|
|
|
camera?.cameraControl?.enableTorch(false)
|
|
camera?.cameraControl?.enableTorch(false)
|
|
|
camera?.cameraControl?.setLinearZoom(linearZoom)
|
|
camera?.cameraControl?.setLinearZoom(linearZoom)
|
|
|
camera?.let(::configureLowLight)
|
|
camera?.let(::configureLowLight)
|
|
|
|
|
+ view.post {
|
|
|
|
|
+ if (view.width > 0 && view.height > 0) focusAt(view.width / 2f, view.height / 2f)
|
|
|
|
|
+ }
|
|
|
onState(CameraState.FREE)
|
|
onState(CameraState.FREE)
|
|
|
}.onFailure { onState(CameraState.ERROR); onMessage("相机初始化失败:${it.message.orEmpty()}") }
|
|
}.onFailure { onState(CameraState.ERROR); onMessage("相机初始化失败:${it.message.orEmpty()}") }
|
|
|
}, executor)
|
|
}, executor)
|
|
@@ -87,6 +92,18 @@ class CameraController(private val context: Context, private val onState: (Camer
|
|
|
camera?.cameraControl?.setLinearZoom(linearZoom)
|
|
camera?.cameraControl?.setLinearZoom(linearZoom)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ fun focusAt(x: Float, y: Float) {
|
|
|
|
|
+ val view = previewView ?: return
|
|
|
|
|
+ val point = view.meteringPointFactory.createPoint(x, y)
|
|
|
|
|
+ val action = FocusMeteringAction.Builder(
|
|
|
|
|
+ point,
|
|
|
|
|
+ FocusMeteringAction.FLAG_AF or FocusMeteringAction.FLAG_AE or FocusMeteringAction.FLAG_AWB,
|
|
|
|
|
+ )
|
|
|
|
|
+ .setAutoCancelDuration(4, TimeUnit.SECONDS)
|
|
|
|
|
+ .build()
|
|
|
|
|
+ camera?.cameraControl?.startFocusAndMetering(action)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
@OptIn(ExperimentalCamera2Interop::class)
|
|
@OptIn(ExperimentalCamera2Interop::class)
|
|
|
private fun configureLowLight(boundCamera: Camera) {
|
|
private fun configureLowLight(boundCamera: Camera) {
|
|
|
runCatching {
|
|
runCatching {
|
|
@@ -101,6 +118,9 @@ class CameraController(private val context: Context, private val onState: (Camer
|
|
|
val noiseReductionModes = cameraInfo.getCameraCharacteristic(
|
|
val noiseReductionModes = cameraInfo.getCameraCharacteristic(
|
|
|
CameraCharacteristics.NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
|
|
CameraCharacteristics.NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
|
|
|
) ?: intArrayOf()
|
|
) ?: intArrayOf()
|
|
|
|
|
+ val autoFocusModes = cameraInfo.getCameraCharacteristic(
|
|
|
|
|
+ CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES,
|
|
|
|
|
+ ) ?: intArrayOf()
|
|
|
val options = CaptureRequestOptions.Builder().apply {
|
|
val options = CaptureRequestOptions.Builder().apply {
|
|
|
lowLightRange?.let {
|
|
lowLightRange?.let {
|
|
|
setCaptureRequestOption(
|
|
setCaptureRequestOption(
|
|
@@ -114,6 +134,12 @@ class CameraController(private val context: Context, private val onState: (Camer
|
|
|
CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITY,
|
|
CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITY,
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
|
|
+ if (autoFocusModes.contains(CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO)) {
|
|
|
|
|
+ setCaptureRequestOption(
|
|
|
|
|
+ CaptureRequest.CONTROL_AF_MODE,
|
|
|
|
|
+ CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO,
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
}.build()
|
|
}.build()
|
|
|
Camera2CameraControl.from(boundCamera.cameraControl).setCaptureRequestOptions(options)
|
|
Camera2CameraControl.from(boundCamera.cameraControl).setCaptureRequestOptions(options)
|
|
|
}
|
|
}
|