【问题标题】:React Native Camera: Access snapped imageReact Native Camera:访问捕捉的图像
【发布时间】:2023-03-30 06:01:01
【问题描述】:

我在我的应用程序中使用 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 方法访问文件时出现以下错误:错误:文件不存在。

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

【问题讨论】:

    标签: ios iphone react-native


    【解决方案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。

    【讨论】:

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

    我在这个应用程序中使用了 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,
      },
    });
    

    【讨论】:

    • 而不是 img : '', 使用 img : null, 并且它将正常工作
    猜你喜欢
    • 1970-01-01
    • 2021-10-22
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多