React Native相机:访问拍摄的图片

3

我正在我的应用程序中使用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个回答

2

你的代码看起来没问题,但有一些“奇怪”的东西。

你将选项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


感谢您的回复。直接使用data.base64似乎最初可以工作,但是我无法从S3打开上传的图像。在我的Mac上预览告诉我文件已损坏或格式不受支持。 使用其他选项似乎可以工作,尽管我会收到一个新错误,告诉我“缓冲区”未定义。这里有什么想法吗? - ppgcc74
抱歉耽搁了。您可能需要添加前缀"data:image/jpeg;base64,${IMAGE_BASE64_STRING}",因此请尝试将"data:image/jpeg;base64,"前缀添加到生成的base64字符串中,看看是否有效。 - jgfidelis
你救了我的一天,兄弟!我已经搜索了一整天才找到这个答案。 - andriansandi

2
我正在使用RNCamera插件开发这个应用程序,这段代码展示了在应用程序中通过相机拍摄的图片。"Original Answer"翻译成"最初的回答"。
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,
  },
});

使用 img : null 替换 img : '',就可以避免出现错误。 - Ginggas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接