React Native Camera:访问捕捉的图像

时间:2018-05-16 14:42:25

标签: ios iphone react-native

我在我的应用中使用react-native-camera插件。我正在尝试拍摄图像,然后立即通过AWS Amplify将其上传到AWS S3存储桶。

我的代码如下:

export default class Camera extends Component {
render() {
    return (
        <View style={styles.container}>
            <RNCamera
                ref={ref => {
                    this.camera = ref;
                }}
                style={styles.preview}
                flashMode={RNCamera.Constants.FlashMode.auto}
                permissionDialogTitle={'Permission to use camera'}
                permissionDialogMessage={'We need your permission to use your phone\'s camera'}
            />
            <TouchableOpacity
                onPress={this.takePicture.bind(this)}
                style={styles.capture}
            >
                <Text style={{fontSize: 15}}> SNAP </Text>
            </TouchableOpacity>
        </View>
    );
}

takePicture = async function () {
    if (this.camera) {
        const options = {base64: true};
        const data = await this.camera.takePictureAsync(options);
        console.log(data.uri);
        uploadPictureToS3(data.uri, "image.jpg");
    }
};
}

function readFile(fileUri) {
    return RNFetchBlob.fs.readFile(fileUri, 'base64').then(data => new Buffer(data, 'base64'));
}

function uploadPictureToS3(uri, key) {
    readFile(uri).then(buffer => {
        Storage.put(key, buffer, {
            contentType: "image/jpeg"
        })
    })
        .then(r => {
            console.log(r);
        })
        .catch(e => {
        console.error(e);
    });
}

尝试使用readFile方法访问文件时出现以下错误:错误:文件不存在。

这里发生了什么?为什么我在拍摄后无法直接从缓存文件夹中读取图像?

2 个答案:

答案 0 :(得分:1)

虽然有一些“怪异”的东西,但你的代码看起来还不错。

您将选项base64传递给takePictureAsync。这使得相机自动返回拍摄照片的base64,但您不会将其用于任何事情。您可以执行uploadPictureToS3(data.base64, "image.jpg");并跳过readFile方法。

另一件事是,不知道为什么会这样,从我们通常做的uri获取图像base64: const filepath = data.uri.split('//')[1]; const imageUriBase64 = await RNFS.readFile(filepath, 'base64');

所以尝试使用const filepath = data.uri.split('//')[1];技巧,而不是直接传递data.uri。

答案 1 :(得分:0)

我正在此应用程序中使用RNCamera插件,此代码通过应用程序中的摄像头显示图像定位

import React, { Component } from 'react';
import { StyleSheet, Text, TouchableOpacity, View, Image } from 'react-native';
import { RNCamera } from 'react-native-camera';

export default class CameraPage extends Component {
    constructor(props) {
        super(props);
        this.state = {
          img : '',
      }
    }
    takePicture = async function(camera) {
        const options = { quality: 0.5, base64: true };
        const data = await camera.takePictureAsync(options);

        this.setState({
          img: data.uri
        })        
      };    
  render() {
    const{img}= this.state;
    return (
      <View style={styles.container}>
        <RNCamera
          style={styles.preview}
          type={RNCamera.Constants.Type.back}
          flashMode={RNCamera.Constants.FlashMode.off}
          permissionDialogTitle={'Permission to use camera'}
          permissionDialogMessage={'We need your permission to use your camera phone'}
        >
          {({ camera}) => {

            return (
              <View style={{ flex: 0, flexDirection: 'row', justifyContent: 'center' }}>
                <TouchableOpacity onPress={() => this.takePicture(camera)} style={styles.capture}>
                  <Text style={{ fontSize: 14 }}> SNAP </Text>
                </TouchableOpacity>                
              </View>
            );
          }}
        </RNCamera>
        <View style={{flex:1,justifyContent: 'center', alignItems: 'center'}}>          
            <Image  source={{uri:img}} style={{  width: 200, height: 200}}/>
        </View>
      </View>
    );
  }


}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'column',
    backgroundColor: 'black',
  },
  preview: {
    flex: 2,
    justifyContent: 'flex-end',
    alignItems: 'center',
  },
  capture: {
    flex: 0,
    backgroundColor: '#fff',
    borderRadius: 5,
    padding: 15,
    paddingHorizontal: `**enter code here**`20,
    alignSelf: 'center',
    margin: 20,
  },
});