相机冻结:如何重新初始化相机组件?

Posted

技术标签:

【中文标题】相机冻结:如何重新初始化相机组件?【英文标题】:Camera Freeze: How to reinitialise camera component? 【发布时间】:2018-04-14 09:03:22 【问题描述】:

使用相机拍照,然后导航到另一个有后退按钮的页面,在点击事件时我再次导航到相机,但这次相机冻结但我可以点击另一张照片。

如果导航流程是相机 => 其他组件(例如相机点击图片视图)=> 相机,则观察到相机冻结。

如果导航流程是其他组件(例如,除了摄像头之外的任何组件)=> 摄像头,则不会发生摄像头冻结。可能需要杀死相机的东西,然后导航应该发生。

包线程:react-native-camera-kit

【问题讨论】:

【参考方案1】:

我已经解决了这个问题,但在互联网上进行了几次搜索后,我使用componentDidMount解决了它

React-navigation 在选项卡之间切换时不会卸载组件。因此,当您离开并返回带有相机组件的屏幕时,它将只是黑色视图。所以一个好的解决方案是使用componentDidMount 并添加两个监听器willFocuswillBlur 来帮助您挂载和卸载视图。

componentDidMount() 
   const  navigation  = this.props;
   navigation.addListener('willFocus', () =>
     this.setState( focusedScreen: true )
   );
   navigation.addListener('willBlur', () =>
     this.setState( focusedScreen: false )
   );
 




    render() 
        const  isPermitted, focusedScreen  = this.state;
        if (isPermitted === null) 
          return (<View style=flex:1, justifyContent:'center',alignItems:'center'>
            <Text>Error</Text>
          </View>);
         else if (isPermitted === false) 
          return (<View style=flex:1, justifyContent:'center',alignItems:'center'>
          <ActivityIndicator size="large" style=color:'blue', fontSize:30 />
            <Text>No Acceas to camera</Text>
          </View>);
         else if (focusedScreen)
          return ( <View>
            <FullPageLoader isVisible=this.state.isLoader TextToShow=this.state.loaderText />
            <CameraKitCameraScreen
            actions= leftButtonText: <Icon name='close' style=color:'white',fontSize:30/>,rightButtonText: <Icon name='images' style=color:'white',fontSize:40/> 
            onBottomButtonPressed=event => this.onBottomButtonPressed(event)
            ref= (cam) => 
              this.camera = cam;
            
            flashImages=
              on: require('./img/flashon.png'),
              off: require('./img/flashoff.png'),
              auto: require('./img/flashauto.png'),
            
            TopTitle=this.state.title
            cameraFlipImage=require('./img/flip-camera.png')
            captureButtonImage=require('./img/capture.png')
            cameraOptions=
              flashMode: 'auto',             // on/off/auto(default)
              focusMode: 'on',               // off/on(default)
              zoomMode: 'on',                // off/on(default)
              ratioOverlayColor: '#00000077'
            
            style=height:'100%'
          />
          </View>);
        else
          return (<Text>Camera Error</Text>);
        
      

参考:https://github.com/react-native-community/react-native-camera/blob/master/docs/react-navigation.md

【讨论】:

【参考方案2】:

对于那些使用 Expo 和 React Native 功能组件的人来说,这变得更加复杂。

对于那些第一次到达的人来说,问题是 React Native 屏幕不会在离开时破坏相机。您可以创建多个摄像头屏幕,但是当您返回到前一个摄像头屏幕时,预览似乎会冻结,因为该屏幕上的摄像头永远不会重新初始化。

我的解决方案是创建一个相机,并根据 UI 的需要有条件地切换 UI 渲染组件。

类似这样的:

import React,  useEffect, useState  from 'react';
import  StyleSheet, View, Button  from 'react-native';
import  Camera  from 'expo-camera';
import * as Permissions from 'expo-permissions';

export default function App() 

   const [hasCameraPermission, setHasCameraPermission] = useState(false);
   const [cameraMode1, setCameraMode1] = useState(true);

   const takePicture = async () => 
        if (cameraMode1) 
           alert("Picture mode 1");
           setCameraMode1(false);
         else 
           alert("Picture mode 2");
           setCameraMode1(true);
        
    

    useEffect(() => 
        async function getCameraStatus() 
            const  status  = await Permissions.askAsync(Permissions.CAMERA);
            setHasCameraPermission(status == 'granted');
        
        getCameraStatus();
    , [hasCameraPermission]);

    return (
      <View style= flex: 1>
        <Camera
              style=[StyleSheet.absoluteFillObject]
        />
        cameraMode1 ?
        <Button
            title="Camera Mode 1"
            onPress=() =>  takePicture() 
        />
        :
        <Button
            title="Camera Mode 2"
            onPress=() =>  takePicture() 
        />
        
       </View>
    );

你可以Test out this code on Expo Snack

【讨论】:

以上是关于相机冻结:如何重新初始化相机组件?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Swift 在 SpriteKit 程序中初始化/移动相机?

UIImagePickerController 相机在翻转和取消几次时冻结

Android 相机 - 有时当我拍照时,应用程序冻结并且相机无法使用

IOS8:AVFoundation 相机冻结

android虚拟机的相机为啥无法使用

Android 相机在 startPreview() 处冻结,没有任何错误信息