重新绑定 CameraX 用例
Rebinding CameraX UseCases
我正在尝试 stop/pause 相机 PreviewView
在图像 processing/detection 期间使用 Firebase MLKit
。要暂停预览,我调用
cameraProvider.unbind(previewUseCase)
这会在最后一帧停止预览,但现在我不知道如何重新启动它。我试过像这样再次绑定预览
cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, preview)
但这会导致 PreviewView
只显示白色,就像它消失了一样,并且在重新启动应用程序之前无法恢复。
当我调用 unbindAll()
时,同样的事情发生了
所以我的问题是如何暂停预览视图,然后在稍后重新启动它?
这是我的代码
fun setupCamera(windowManager: WindowManager, previewView: PreviewView){
_cameraProvider = _cameraProviderFuture.get()
_preview = Preview.Builder()
.setTargetRotation(windowManager.defaultDisplay.rotation)
.build()
_preview.setSurfaceProvider(previewView.previewSurfaceProvider)
_cameraSelector = CameraSelector.Builder()
.requireLensFacing(_requiredCameraLens)
.build()
_imageAnalyzer = ImageAnalysis.Builder()
.setTargetResolution(Size(_imageWidth, _imageHeight))
.setBackpressureStrategy(_imageBackpressureStrategy)
.build()
_imageAnalyzer.setAnalyzer(_imageExecutor,_analyzer)
startPreview()
_cameraProvider.bindToLifecycle(_lifecycleOwner, _cameraSelector, _imageAnalyzer)
}
// Called after image processing has finished
fun startPreview(){
_cameraProvider.bindToLifecycle(_lifecycleOwner, _cameraSelector, _preview)
}
// Called when object is detected in an image
fun stopPreview(){
_cameraProvider.unbind(_preview)
}
我没有在 Kotlin 中测试我的解决方案,但它在 Java 中运行良好。实际上,如果您只是调用 cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, preview) 它不会真正重新绑定您的预览。事实上,您必须重新创建预览并重置表面提供者。例如在 Java 中,当我想重新绑定我的预览时,我使用:
public void rebindPreview(){
Preview preview = new Preview.Builder()
.setTargetName("Preview")
.build();
preview.setSurfaceProvider(previewView.getPreviewSurfaceProvider());
Camera camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageCapture);
}
我假设对于 Kotlin,您可以这样做:
fun rebindPreview(){
_preview = Preview.Builder()
.setTargetRotation(windowManager.defaultDisplay.rotation)
.setTargetName("Preview")
.build()
_preview.setSurfaceProvider(previewView.previewSurfaceProvider)
_cameraProvider.bindToLifecycle(_lifecycleOwner, _cameraSelector, _preview)
}
我正在尝试 stop/pause 相机 PreviewView
在图像 processing/detection 期间使用 Firebase MLKit
。要暂停预览,我调用
cameraProvider.unbind(previewUseCase)
这会在最后一帧停止预览,但现在我不知道如何重新启动它。我试过像这样再次绑定预览
cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, preview)
但这会导致 PreviewView
只显示白色,就像它消失了一样,并且在重新启动应用程序之前无法恢复。
当我调用 unbindAll()
所以我的问题是如何暂停预览视图,然后在稍后重新启动它?
这是我的代码
fun setupCamera(windowManager: WindowManager, previewView: PreviewView){
_cameraProvider = _cameraProviderFuture.get()
_preview = Preview.Builder()
.setTargetRotation(windowManager.defaultDisplay.rotation)
.build()
_preview.setSurfaceProvider(previewView.previewSurfaceProvider)
_cameraSelector = CameraSelector.Builder()
.requireLensFacing(_requiredCameraLens)
.build()
_imageAnalyzer = ImageAnalysis.Builder()
.setTargetResolution(Size(_imageWidth, _imageHeight))
.setBackpressureStrategy(_imageBackpressureStrategy)
.build()
_imageAnalyzer.setAnalyzer(_imageExecutor,_analyzer)
startPreview()
_cameraProvider.bindToLifecycle(_lifecycleOwner, _cameraSelector, _imageAnalyzer)
}
// Called after image processing has finished
fun startPreview(){
_cameraProvider.bindToLifecycle(_lifecycleOwner, _cameraSelector, _preview)
}
// Called when object is detected in an image
fun stopPreview(){
_cameraProvider.unbind(_preview)
}
我没有在 Kotlin 中测试我的解决方案,但它在 Java 中运行良好。实际上,如果您只是调用 cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, preview) 它不会真正重新绑定您的预览。事实上,您必须重新创建预览并重置表面提供者。例如在 Java 中,当我想重新绑定我的预览时,我使用:
public void rebindPreview(){
Preview preview = new Preview.Builder()
.setTargetName("Preview")
.build();
preview.setSurfaceProvider(previewView.getPreviewSurfaceProvider());
Camera camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageCapture);
}
我假设对于 Kotlin,您可以这样做:
fun rebindPreview(){
_preview = Preview.Builder()
.setTargetRotation(windowManager.defaultDisplay.rotation)
.setTargetName("Preview")
.build()
_preview.setSurfaceProvider(previewView.previewSurfaceProvider)
_cameraProvider.bindToLifecycle(_lifecycleOwner, _cameraSelector, _preview)
}