在React Native中将图像存储在Realm数据库中

时间:2018-12-27 07:15:45

标签: android react-native

let realm ;
let image;
export default class Home extends React.Component {

constructor(props){
super(props);
this.state = {

  ImageSource: null,
  data: null,
  Image_TAG: '',

}

realm = new Realm({
  schema: [{name: 'fields',
  properties:
  {
    id: {type: 'int',   default: 0},
    path: 'string',
    tag : 'string',
    data : 'string'
  }}], schemaVersion: 0
});

   }

  selectPhotoTapped() {
 const options = {
   quality: 1.0,
   maxWidth: 500,
   maxHeight: 500,
   storageOptions: {
     skipBackup: true
   }
 };

 ImagePicker.showImagePicker(options, (response) => {
   console.log('Response = ', response);

   if (response.didCancel) {
     console.log('User cancelled photo picker');
   }
   else if (response.error) {
     console.log('ImagePicker Error: ', response.error);
   }
   else if (response.customButton) {
     console.log('User tapped custom button: ', response.customButton);
   }
   else {
     let source = { uri: response.uri };

     this.setState({

       ImageSource: source,
       data: response.data

     });
   }
 });
   }

  checkNet = () => {
    NetInfo.isConnected.fetch().then(isConnected => {
             if(isConnected)
             {
                 this.uploadImageToServer();
             }
             else{
               this.uploadImageToDatabase();
             }
  })
      }

  uploadImageToDatabase= () => {

ImgToBase64.getBase64String(this.state.data).then(base64String =>
  //doSomethingWith(base64String))
  {image = base64String})
  .catch(err =>{}
  );
  realm.write(() => {

  var ID = realm.objects('fields').length + 1;

   realm.create('fields', {
     id: ID,
     path: this.state.ImageSource,
     tag: this.state.Image_TAG,
     data: image,
    });

});

   }

   uploadImageToServer = () => {

 RNFetchBlob.fetch('POST', 'http://192.168.0.76/survey/upload_image.php', {
   Authorization: "Bearer access-token",
   otherHeader: "foo",
   'Content-Type': 'multipart/form-data',
 }, [
     { name: 'image', filename: 'image.png', type: 'image/png', data: this.state.data },
     { name: 'image_tag', data: this.state.Image_TAG }
   ]).then((resp) => {

     var tempMSG = resp.data;

     tempMSG = tempMSG.replace(/^"|"$/g, '');

     //Alert.alert(tempMSG);
     this.state.response = resp.data;

   }).catch((err) => {
     // ...
     Alert.alert("Some Error occured;");
   })

   }

   _send(){
    this.props.navigation.navigate("ViewScreen")
  }
   _next(){
    this.props.navigation.navigate("HomeScreen")
  }


  render() {
    return (
  <View style={styles.container}>

  <ScrollView>

  <Button
  onPress={this._send.bind(this)}
  title="View all results"
  color="green"
  />

  <Button
  onPress={this._next.bind(this)}
  title="Next"
  color="#841584"/>

  <TouchableOpacity onPress={this.selectPhotoTapped.bind(this)}>

      <View style={styles.ImageContainer}>

        {this.state.ImageSource === null ? <Text>Select a Photo</Text> :
          <Image style={styles.ImageContainer} source= 
   {this.state.ImageSource} />
        }

      </View>

    </TouchableOpacity>


    <TextInput

      placeholder="Enter Image Name "

      onChangeText={data => this.setState({ Image_TAG: data })}

      underlineColorAndroid='transparent'

      style={styles.TextInputStyle}
    />


    <TouchableOpacity onPress={this.checkNet.bind(this)} activeOpacity={0.6} style={styles.button} >

      <Text style={styles.TextStyle}> UPLOAD IMAGE TO SERVER </Text>

    </TouchableOpacity>

    </ScrollView>
</View>


    );
  }
}

以上代码是Home.js文件。

 export default class ViewImages extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      data :""
    }
  }
  componentWillMount() {
      let realm = new Realm();
      let result = realm.objects('fields');
      this.state.data = result;
  }

  render() {
    return (
      <View>
      <ScrollView>
       <Text style= 
{{backgroundColor:'green',fontSize:20}}>WElllllllllllllcome to view</Text>
  <FlatList
    data={this.state.data}
    showsVerticalScrollIndicator={false}
    renderItem={({item}) =>


    <View style={{flexDirection: 'row' ,marginBottom:10,borderWidth: 1,borderColor: 'black', padding:10,marginLeft:5,marginRight:5}}>
        <Image source={{ uri: `data:image/png;base64,${item.data}`}} style={{height:35, width:32,justifyContent:'flex-start',marginRight:20,marginLeft:20}} />
        <Text style={{fontFamily: 'Verdana',fontSize: 20,justifyContent: 'center',marginLeft:20,marginRight:20,fontWeight: 'bold'}}>{item.tag}</Text>

    </View>
    }
    keyExtractor={item => item.name}
  />
  </ScrollView>
  </View>
);
  }
}

上面的代码是viewscreen.js文件 我想做的是基于Internet上传图像。如果设备连接到Internet,则它将直接上传到服务器,如果没有连接,则它将图像标记源和图像的base64存储在领域数据库中。查看结果以查看来自领域数据库的所有上载图像,然后它没有显示任何内容。我在这里做错了什么?我的代码是否在领域中插入图像数据?

3 个答案:

答案 0 :(得分:0)

我可以看到的一个问题是state更新

componentWillMount() {
  let realm = new Realm();
  let result = realm.objects('fields');
  this.state.data = result;
}

您已更新状态值,但不会重新渲染组件。您需要更新状态,例如

this.setState({ data:result })

this.state.data = result;
this.setState({})

我希望第一种方法更新state

答案 1 :(得分:0)

是的!我知道了,imagepicker中的response.data返回了图像的基本encoding64版本,我们可以直接将其写入数据库,这意味着我不需要使用其他库更改为base64版本。

答案 2 :(得分:0)

对于正在考虑在Realm中存储大文件(例如图像或视频)的人们,我建议阅读官方文档:https://docs.realm.io/sync/using-synced-realms/syncing-data#syncing-large-objects-photos-videos-etc 哪个状态

  

同步大对象(照片,视频等)

     

虽然Realm数据库可用于存储二进制数据,但通常   不建议将Blob数据存储在Realm中,因为它可以   领域同步效率低下。用于同步更改的差异算法   在场级上工作,因此如果单张图像发生变化,   整个图像将需要重新同步,而不仅仅是单个   改变的位。相同的逻辑可以应用于大型JSON Blob   也存储为大字符串字段-如果是单个   键值更改,则整个JSON必须重新同步。相反,如果你   想要使用Realm同步来传输图像,我们建议使用   领域同步将图像传输到ROS,然后进行事件   处理程序对新图像做出反应,从Realm中删除该图像并存储   将其存储在某些对象存储(例如S3)中,然后只需存储一个   对Realm数据库中URL的引用。如果客户想看   他们可以再次通过REST或URL从完整的图像中提取图像。   文件访问。