aboozaid/react-native-facerecognition

Ui suggestion

Closed this issue · 2 comments

Hi @assemmohamedali,
Take a look at this graphic that I made.
Let me know what you think.

import React, { Component } from 'react';
import {
  Platform,
  StyleSheet,
  Text,
  View,
  TouchableOpacity,
  ToastAndroid,
  ListView,
  TextInput,
  TouchableHighlight,
  DeviceEventEmitter,
  StatusBar,
  Image,
} from 'react-native';
import { RNCamera } from 'react-native-camera';
import Face from 'react-native-facerecognition';
import DialogManager, {
  SlideAnimation,
  DialogContent,
  DialogTitle,
  DialogButton,
} from 'react-native-dialog-component';

export default class App extends Component {
  constructor(props) {
    super(props);
    this.ds = new ListView.DataSource({
      rowHasChanged: (r1, r2) => r1 !== r2,
    });
    const faces = [];
    this.state = {
      dataSource: this.ds.cloneWithRows(faces),
      captured: 1,
      faces: faces,
      type: 'front',
    };
  }
  componentDidMount() {
    StatusBar.setHidden(true);
    DeviceEventEmitter.addListener(
      'onFaceRecognized',
      this.onFaceRecognized.bind(this)
    );
    DeviceEventEmitter.addListener('onClean', this.onClean.bind(this));
  }
  render() {
    return (
      <View style={styles.container}>
        <RNCamera
          ref={ref => {
            this.camera = ref;
          }}
          style={styles.preview}
          type={this.state.type}
          permissionDialogTitle={'Permission to use camera'}
          permissionDialogMessage={
            'We need your permission to use your camera phone'
          }
          onMountError={msg => this.cameraError(msg)}
          onCameraReady={() => {
            this.onCameraReady();
          }}>
          <View
            style={{
              flex: 0,
              flexDirection: 'row',
              justifyContent: 'flex-end',
            }}>
            <TouchableOpacity
              onPress={this.recognizePicture.bind(this)}
              style={styles.capture}>
              <Image
                style={{ width: 35, height: 35 }}
                source={{
                  uri:
                    'https://cdn3.iconfinder.com/data/icons/antivirus-internet-security-thin-colored-outline/33/facial_recognition-512.png',
                }}
              />
            </TouchableOpacity>
            <TouchableOpacity
              onPress={() =>
                this.setState({
                  type: this.state.type === 'back' ? 'front' : 'back',
                })
              }
              style={styles.capture}>
              <Image
                style={{ width: 35, height: 35 }}
                source={{
                  uri:
                    'https://user-images.githubusercontent.com/20476002/43048582-2fa1b864-8dea-11e8-968a-2bb209302604.png',
                }}
              />
            </TouchableOpacity>
            <TouchableOpacity
              onPress={() => this.clean()}
              style={styles.capture}>
              <Image
                style={{ width: 35, height: 35 }}
                source={{
                  uri:
                    'https://cdn2.iconfinder.com/data/icons/basic-4/512/delete-512.png',
                }}
              />
            </TouchableOpacity>
          </View>
          <View style={{ flex: 1, justifyContent: 'flex-end' }}>
            <TouchableOpacity
              onPress={this.takePicture.bind(this)}
              style={styles.capture}>
              <Image
                style={{ width: 35, height: 35 }}
                source={{
                  uri:
                    'https://user-images.githubusercontent.com/20476002/43048598-67bed272-8dea-11e8-9736-a6ebb6e28362.png',
                }}
              />
            </TouchableOpacity>
          </View>
        </RNCamera>
      </View>
    );
  }

  onFaceRecognized(data) {
    ToastAndroid.show(
      'Recognized: ' + data.name + ' Distance: ' + data.distance,
      ToastAndroid.LONG
    );
  }
  onClean(msg) {
    this.setState({ faces: [] });
    ToastAndroid.show(msg, ToastAndroid.SHORT);
  }
  clean() {
    Face.Clean();
  }
  onCameraReady() {
    Face.Start(
      Face.Detection.DEEP,
      success => {
        ToastAndroid.show('Train initialized', ToastAndroid.SHORT);
      },
      error => {
        ToastAndroid.show(error, ToastAndroid.LONG);
      }
    );
  }

  takePicture = async function() {
    if (this.camera) {
      const options = { width: 200, base64: true };
      const data = await this.camera.takePictureAsync(options);
      Face.Detect(
        data.base64,
        detected => {
          ToastAndroid.show(detected, ToastAndroid.SHORT);
          this.setState({ image64: data.base64 });
          this.onFaceDetect();
        },
        error => {
          ToastAndroid.show(error, ToastAndroid.SHORT);
        }
      );
    }
  };
  recognizePicture = async function() {
    if (this.camera) {
      const options = { width: 200, base64: true };
      const data = await this.camera.takePictureAsync(options);
      Face.Detect(
        data.base64,
        detected => {
          ToastAndroid.show(detected, ToastAndroid.SHORT);
          Face.Identify(data.base64, unrecognized => {
            ToastAndroid.show(unrecognized, ToastAndroid.SHORT);
          });
        },
        error => {
          ToastAndroid.show(error, ToastAndroid.SHORT);
        }
      );
      console.log(data.uri);
    }
  };
  onFaceDetect() {
    if (this.state.faces.length == 0) this.newFaceDetected();
    else {
      DialogManager.show(
        {
          title: 'Trained Faces',
          titleAlign: 'center',
          haveOverlay: false,
          animationDuration: 200,
          SlideAnimation: new SlideAnimation({ slideFrom: 'top' }),
          children: (
            <DialogContent>
              <View>
                <ListView
                  dataSource={this.state.dataSource}
                  renderRow={this.renderRow.bind(this)}
                />
              </View>
              <DialogButton
                text="Close"
                align="right"
                onPress={() => DialogManager.dismiss()}
              />
              <DialogButton
                text="New Face"
                align="right"
                onPress={() => this.newFaceDetected()}
              />
            </DialogContent>
          ),
        },
        () => {
          console.log('callback - show');
        }
      );
    }
  }
  newFaceDetected() {
    DialogManager.show(
      {
        title: 'Train Face',
        titleAlign: 'center',
        haveOverlay: false,
        animationDuration: 200,
        SlideAnimation: new SlideAnimation({ slideFrom: 'top' }),
        children: (
          <DialogContent>
            <View>
              <TextInput
                placeholder="face name"
                onChangeText={Fname => this.setState({ Fname })}
              />
            </View>
            <DialogButton text="Save" onPress={() => this.newFaceImage()} />
          </DialogContent>
        ),
      },
      () => {
        console.log('callback - show');
      }
    );
  }
  newFaceImage() {
    const faces = [
      ...this.state.faces,
      { Fname: this.state.Fname, captured: this.state.captured },
    ];
    const images = { image64: this.state.image64, Fname: this.state.Fname };
    Face.Training(images, result => alert(result), err => alert(err));
    this.setState({ dataSource: this.ds.cloneWithRows(faces), faces });
    DialogManager.dismissAll();
  }
  saveCaptureImage(faceData) {
    if (faceData.captured == 5)
      ToastAndroid.show('More photos are not allowed', ToastAndroid.SHORT);
    else {
      const slice = this.state.faces.slice();
      slice.map(face => {
        if (face.Fname == faceData.Fname) face.captured++;
      });
      this.setState({ dataSource: this.ds.cloneWithRows(slice) });
      const images = { image64: this.state.image64, Fname: faceData.Fname };
      Face.Training(images, result => alert(result), err => alert(err));
    }
    DialogManager.dismiss();
  }
  renderRow(rowData) {
    return (
      <TouchableHighlight
        onPress={() => this.saveCaptureImage(rowData)}
        underlayColor="transparent">
        <View
          style={{
            flex: 1,
            flexDirection: 'row',
            padding: 15,
            alignItems: 'center',
            borderColor: '#D7D7D7',
            borderBottomWidth: 1,
          }}>
          <Text style={{ fontSize: 16 }}>{rowData.captured}</Text>
          <View style={{ paddingLeft: 20 }}>
            <Text style={{ fontSize: 18 }}>{rowData.Fname}</Text>
          </View>
        </View>
      </TouchableHighlight>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'column',
    backgroundColor: 'white',
  },
  preview: {
    flex: 1,
    //justifyContent: 'flex-end',
    //alignItems: 'center',
  },
  capture: {
    flex: 0,
    //backgroundColor: '#D7D7D7',
    //borderRadius: 5,
    padding: 10,
    //paddingHorizontal: 10,
    alignSelf: 'center',
    margin: 10,
  },
});

Sounds like everything is upside down, Did you try it first?

@assemmohamedali :