web-dev-qa-db-ja.com

expo反応ネイティブカメラを使用して写真をスナップする方法?

React Expoのネイティブを使用し始めたばかりなので、混乱しているようです。そのため、メイン画面にインポートしたカメラコンポーネントを作成しました。すべてが問題ありません。しかし、写真を撮ります。スナップアイコンをクリックして画像を保存できません。見逃したコンポーネントはありますか?以下のCameraComponentクラスのみを投稿しました。

Camera.js

class CameraComponent extends Component {

  state = {
    hasCameraPermission: null,
    type: Camera.Constants.Type.back
  }

  async componentWillMount() {
    const { status } = await Permissions.askAsync(Permissions.CAMERA);
    this.setState({ hasCameraPermission: status === 'granted' })
  }

  render() {
    const { hasCameraPermission } = this.state

    if (hasCameraPermission === null) {
      return <View />
    }
    else if (hasCameraPermission === false) {
      return <Text> No access to camera</Text>
    }
    else {
      return (
        <View style={{ flex: 1 }}>
          <Camera 
            style={{ flex: 1, justifyContent: 'space-between' }}
            type={this.state.type}
          >
            <Header
              searchBar
              rounded
              style={{
                position: 'absolute',
                backgroundColor: 'transparent',
                left: 0,
                top: 0,
                right: 0,
                zIndex: 100,
                alignItems: 'center'
              }}
            >
              <View style={{ flexDirection: 'row', flex: 4 }}>
                <Ionicons name="md-camera" style={{ color: 'white' }} />
                <Item style={{ backgroundColor: 'transparent' }}>
                  <Icon name="ios-search" style={{ color: 'white', fontSize: 24, fontWeight: 'bold' }}></Icon>
                </Item>
              </View>

              <View style={{ flexDirection: 'row', flex: 2, justifyContent: 'space-around' }}>
                <Icon name="ios-flash" style={{ color: 'white', fontWeight: 'bold' }} />
                <Icon
                  onPress={() => {
                    this.setState({
                      type: this.state.type === Camera.Constants.Type.back ?                                        
                                            Camera.Constants.Type.front :
                                            Camera.Constants.Type.back
                    })
                  }}
                  name="ios-reverse-camera"
                  style={{ color: 'white', fontWeight: 'bold' }}
                />
              </View>
            </Header>

            <View style={{ flexDirection: 'row', justifyContent: 'space-between', paddingHorizontal: 30, marginBottom: 15, alignItems: 'flex-end' }}>
              <Ionicons name="ios-map" style={{ color: 'white', fontSize: 36 }}></Ionicons>
              <View></View>
              <View style={{ alignItems: 'center' }}>
                <MaterialCommunityIcons name="circle-outline"   // This is the icon which should take and save image
                  style={{ color: 'white', fontSize: 100 }}
                ></MaterialCommunityIcons>
                <Icon name="ios-images" style={{ color: 'white', fontSize: 36 }} />
              </View>
            </View>
          </Camera>
        </View>
      )
    }
  }
}

export default CameraComponent;

中央のアイコン、つまり円のアイコンは自動的に画像を取得して保存します。

3
Arjun Kashyap

非同期のtakePictureAsync関数が戻るときに「onPictureSaved」を使用して、写真オブジェクトを取得できます。

  takePicture = () => {
      if (this.camera) {
          this.camera.takePictureAsync({ onPictureSaved: this.onPictureSaved });
      }
   };

  onPictureSaved = photo => {
      console.log(photo);
  } 

ビューには、refを持つCameraコンポーネントがあります。

<Camera style={styles.camera} type={this.state.type} ref={(ref) => { this.camera = ref }} >

プレス時にtakePicture関数を呼び出すボタンと同様に:

<TouchableOpacity style={styles.captureButton} onPress={this.takePicture} />
2
Dilan

したがって、写真を撮るには「サークルアイコン」を指定する必要があります。まず、カメラに参照を追加します

<Camera style={{ flex: 1 }}
      ref={ (ref) => {this.camera = ref} }
      type={this.state.type}>

次に、実際にアプリに写真を撮るように指示する関数を作成します。

 async snapPhoto() {       
    console.log('Button Pressed');
    if (this.camera) {
       console.log('Taking photo');
       const options = { quality: 1, base64: true, fixOrientation: true, 
       exif: true};
       await this.camera.takePictureAsync(options).then(photo => {
          photo.exif.Orientation = 1;            
           console.log(photo);            
           });     
     }
    }

次に、アイコンにonPress()を付けて写真を撮ります。私はこのようなことをしました。

<TouchableOpacity style={styles.captureButton} onPress={this.snapPhoto.bind(this)}>
                <Image style={{width: 100, height: 100}} source={require('../assets/capture.png')}          
                />
            </TouchableOpacity>

また、画像プレビューなどをレンダリングするビューを作成することもできます。 Expoのドキュメントには、入門に関するかなり良い例があります。 Expoは 'Camera'と呼ばれるキャッシュされたフォルダーを作成し、そこに画像が最初にあることに注意してください。

2
DirtyDaver

独自の「handle」メソッド内でtakePictureAsync関数を呼び出せるようにするには、Cameraクラスに参照を追加する必要があります。

cameraRef = React.createRef();

<Camera ref={this.cameraRef}>...</Camera>

参照されるカメラのメソッドを呼び出すときは、「。current」を忘れないでください。

handlePhoto = async () => {
  if(this.cameraRef){
    let photo = await this.cameraRef.current.takePictureAsync();
    console.log(photo);
  }  
}

次に、写真スナップボタンとして機能するタッチ可能な要素で 'handle'メソッドを呼び出すだけです。

<TouchableOpacity 
  style={{width:60, height:60, borderRadius:30, backgroundColor:"#fff"}} 
  onPress={this.handlePhoto} />

コンソールにログインして写真を見ることができるはずです。

1
Stephanos

これを実際の物理デバイスで実行しようとしていますか?エミュレータで写真を撮影することはできません。

0
mediaguru