使用当前的CameraX 1.0.0
版本,有以下两种方法:
每隔 X 秒自动对焦:
previewView.afterMeasured {
val autoFocusPoint = SurfaceOrientedMeteringPointFactory(1f, 1f)
.createPoint(.5f, .5f)
try {
val autoFocusAction = FocusMeteringAction.Builder(
autoFocusPoint,
FocusMeteringAction.FLAG_AF
).apply {
setAutoCancelDuration(2, TimeUnit.SECONDS)
}.build()
camera.cameraControl.startFocusAndMetering(autoFocusAction)
} catch (e: CameraInfoUnavailableException) {
Log.d("ERROR", "cannot access camera", e)
}
}
焦点点击:
previewView.afterMeasured {
previewView.setOnTouchListener { _, event ->
return@setOnTouchListener when (event.action) {
MotionEvent.ACTION_DOWN -> {
true
}
MotionEvent.ACTION_UP -> {
val factory: MeteringPointFactory = SurfaceOrientedMeteringPointFactory(
previewView.width.toFloat(), previewView.height.toFloat()
)
val autoFocusPoint = factory.createPoint(event.x, event.y)
try {
camera.cameraControl.startFocusAndMetering(
FocusMeteringAction.Builder(
autoFocusPoint,
FocusMeteringAction.FLAG_AF
).apply {
disableAutoCancel()
}.build()
)
} catch (e: CameraInfoUnavailableException) {
Log.d("ERROR", "cannot access camera", e)
}
true
}
else -> false
}
}
}
afterMeasured扩展函数是一个简单的实用工具:(感谢ch271828n 改进它)
inline fun View.afterMeasured(crossinline block: () -> Unit) {
if (measuredWidth > 0 && measuredHeight > 0) {
block()
} else {
viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.GlobalLayoutListener {
override fun onGlobalLayout() {
if (measuredWidth > 0 && measuredHeight > 0) {
viewTreeObserver.removeOnGlobalLayoutListener(this)
block()
}
}
})
}
}
可以使用Camera
对象来获取
val camera = cameraProvider.bindToLifecycle(
this@Activity, cameraSelector, previewView
)
setAutoCancelDuration(X, TimeUnit.SECONDS)
,每隔 X 秒就会取消当前的对焦动作并重新开始(至少这是我从文档中理解的)。 如果您将setAutoCancel
替换为disableAutoCancel()
,则相机在打开时将进行对焦,然后再也不会调整对焦了。 - MatPagSurfaceOrientedMeteringPointFactory
构造函数的文档,您可以使用标准化坐标,即最大值等于 1.0 的坐标。在这种简单情况下,当我们想要根据中心点调整焦点时,我们甚至可以更简单地准备我们的测光点(不需要PreviewView
):val autoFocusPoint = SurfaceOrientedMeteringPointFactory(1f, 1f).createPoint(.5f, .5f)
。 - Andrei K.afterMeasured
有一个bug:经常它的回调函数从未被调用。这里是一个修复方法:https://dev59.com/TlMH5IYBdhLWcg3w0DS9#70304116 - ch271828n