【问题标题】:how can I freeze cameraX preview in Android?如何在 Android 中冻结 cameraX 预览?
【发布时间】:2020-04-28 20:06:16
【问题描述】:

我希望相机在按下图像捕捉按钮时冻结预览。我看过其他堆栈溢出问题,但它们已经过时了。

我使用的cameraX版本:1.0.0-beta03

任何帮助将不胜感激。谢谢

【问题讨论】:

    标签: android android-camerax


    【解决方案1】:

    目前还没有“正确”的方法来实现它,但实现它的几种方法包括:

    • 通过取消绑定Preview 用例来停止预览流,拍照,然后绑定一个 Preview 用例以继续预览流。 要使这种方法起作用,您还需要绑定ImageAnalysis 用例,因为如果ImageCapture 是唯一绑定的用例,则无法拍照(另一个PreviewImageAnalysis 用例也必须受约束,请查看the possible use case combinations 上的官方文档)。虽然这种方法有效,但它会导致在调用 ImageCapture 回调的那一刻与继续预览时之间存在轻微延迟,在此期间屏幕将是空白的。

    • 在您拍照的那一刻,使用来自ImageAnalysis 的最新帧将其显示在预览的顶部,您可以将帧(ImageProxy-)转换为Bitmap 并显示在一个ImageView。调用 ImageCapture 回调后,移除框架并继续预览。

    编辑:

    从相机视图版本 1.0.0-alpha12 开始,您可以使用 PreviewView.getBitmap() 获得预览的 Bitmap 表示。使用此方法,您可以在用户拍照时获取预览的Bitmap 表示,将其显示在ImageView 中的预览顶部,然后一旦图像捕获结果可用,隐藏图像。

    【讨论】:

    • 如何将预览视图设为空白?如何去除框架?
    【解决方案2】:

    另外,我认为您可以尝试创建(作为一种解决方法)自定义 LifecycleOwner 包装器,并在您想要暂停预览时手动将生命周期状态设置为 ON_PAUSE。所以它会是这样的:

    class CameraXLifecycleOwner : LifecycleOwner {
    
        private val lifecycle = LifecycleRegistry(this)
    
        private val observer = object : LifecycleObserver {
            @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
            fun onCreate() {
                lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
            }
    
            @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
            fun onResume() {
                lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
            }
    
            @OnLifecycleEvent(Lifecycle.Event.ON_START)
            fun onStart() {
                lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_START)
            }
    
            @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
            fun onPause() {
                lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE)
            }
    
            @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
            fun onStop() {
                lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
            }
    
            @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
            fun onDestroy() {
                lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
            }
    }
    
    fun attachLifecycleOwner(lifecycleOwner: LifecycleOwner) {
        lifecycle.currentState = lifecycleOwner.lifecycle.currentState
        lifecycleOwner.lifecycle.addObserver(observer)
    }
    
    fun detachLifecycleOwner(lifecycleOwner: LifecycleOwner) {
        lifecycleOwner.lifecycle.removeObserver(observer)
    }
    
    fun pauseCamera() {
        lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    }
    
    fun resumeCamera() {
        lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
    }
    
    override fun getLifecycle(): Lifecycle = lifecycle
    

    }

    然后,您可以通过将默认片段的 viewLifecycleOwner 传递给 attachLifecycleOwner() 来包装它,这样包装器将重复所有 viewLifecycleOwner 的状态,但是您也可以调用 pauseCamera()/resumeCamera() 来手动更改伪装 onPause/onResume 状态的状态改变。不确定这是不是最好的主意,但这是一个主意。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多