skip to Main Content

I want to implement blur image detection for my react native application. I have successfully imported the opencv library. But unfortunately the reference I’m using is outdated and uses old react native syntax. Can anyone convert this code:

import React, { Component } from 'react';
import {
  AppRegistry,
  View,
  Text,
  Platform,
  Image,
  TouchableOpacity,
} from 'react-native';
import { RNCamera as Camera } from 'react-native-camera';
import Toast, {DURATION} from 'react-native-easy-toast'

import styles from '../Styles/Screens/CameraScreen';
import OpenCV from '../NativeModules/OpenCV';
import CircleWithinCircle from '../assets/svg/CircleWithinCircle';

export default class CameraScreen extends Component {
  constructor(props) {
    super(props);

    this.takePicture = this.takePicture.bind(this);
    this.checkForBlurryImage = this.checkForBlurryImage.bind(this);
    this.proceedWithCheckingBlurryImage = this.proceedWithCheckingBlurryImage.bind(this);
    this.repeatPhoto = this.repeatPhoto.bind(this);
    this.usePhoto = this.usePhoto.bind(this);
  }

  state = {
    cameraPermission: false,
    photoAsBase64: {
      content: '',
      isPhotoPreview: false,
      photoPath: '',
    },
  };

  checkForBlurryImage(imageAsBase64) {
    return new Promise((resolve, reject) => {
      if (Platform.OS === 'android') {
        OpenCV.checkForBlurryImage(imageAsBase64, error => {
          // error handling
        }, msg => {
          resolve(msg);
        });
      } else {
        OpenCV.checkForBlurryImage(imageAsBase64, (error, dataArray) => {
          resolve(dataArray[0]);
        });
      }
    });
  }

  proceedWithCheckingBlurryImage() {
    const { content, photoPath } = this.state.photoAsBase64;

    this.checkForBlurryImage(content).then(blurryPhoto => {
      if (blurryPhoto) {
        this.refs.toast.show('Photo is blurred!',DURATION.FOREVER);
        return this.repeatPhoto();
      }
      this.refs.toast.show('Photo is clear!', DURATION.FOREVER);
      this.setState({ photoAsBase64: { ...this.state.photoAsBase64, isPhotoPreview: true, photoPath } });
    }).catch(err => {
      console.log('err', err)
    });
  }

  async takePicture() {
    if (this.camera) {
      const options = { quality: 0.5, base64: true };
      const data = await this.camera.takePictureAsync(options);
      this.setState({
        ...this.state,
        photoAsBase64: { content: data.base64, isPhotoPreview: false, photoPath: data.uri },
      });
      this.proceedWithCheckingBlurryImage();
    }
  }


  repeatPhoto() {
    this.setState({
      ...this.state,
      photoAsBase64: {
        content: '',
        isPhotoPreview: false,
        photoPath: '',
      },
    });
  }

  usePhoto() {
    // do something, e.g. navigate
  }


  render() {
    if (this.state.photoAsBase64.isPhotoPreview) {
      return (
        <View style={styles.container}>
          <Toast ref="toast" position="center" />
          <Image
            source={{ uri: `data:image/png;base64,${this.state.photoAsBase64.content}` }}
            style={styles.imagePreview}
          />
          <View style={styles.repeatPhotoContainer}>
            <TouchableOpacity onPress={this.repeatPhoto}>
              <Text style={styles.photoPreviewRepeatPhotoText}>
                Repeat photo
              </Text>
            </TouchableOpacity>
          </View>
          <View style={styles.usePhotoContainer}>
            <TouchableOpacity onPress={this.usePhoto}>
              <Text style={styles.photoPreviewUsePhotoText}>
                Use photo
              </Text>
            </TouchableOpacity>
          </View>
        </View>
      );
    }

    return (
      <View style={styles.container}>
        <Camera
          ref={cam => {
            this.camera = cam;
          }}
          style={styles.preview}
          permissionDialogTitle={'Permission to use camera'}
          permissionDialogMessage={'We need your permission to use your camera phone'}
        >
          <View style={styles.takePictureContainer}>
            <TouchableOpacity onPress={this.takePicture}>
              <View>
                <CircleWithinCircle />
              </View>
            </TouchableOpacity>
          </View>
        </Camera>
        <Toast ref="toast" position="center" />
      </View>
    );
  }
}


AppRegistry.registerComponent('CameraScreen', () => CameraScreen);

Migrate constructor function and props into a functional component.

2

Answers


  1. The necessary steps that must be considered before altering the class-based components to functional components –

    1. Use a function rather than a class.
    2. Eliminate the constructor.
    3. Preserve the return; delete the render() method.
    4. Before all methods,add const.
    5. State every time the component.
    6. Delete all occurrences of this in the component.
    7. Use useState to set the starting state.
    8. alter this.
    9. setState() To update the state, call the function you named in the previous step.
    10. useEffect() have to be used instead of componentDidMount and also
      to achieve component life cycle methods.

    Here is a good document on How To Convert React Class Components to Functional Components with React Hooks

    And for you code, here is the converted component. Please verify.

    import React, { useState, useRef } from 'react';
    import { View, Text, Platform, Image, TouchableOpacity } from 'react-native';
    import { RNCamera as Camera } from 'react-native-camera';
    import Toast, { DURATION } from 'react-native-easy-toast';
    
    import styles from '../Styles/Screens/CameraScreen';
    import OpenCV from '../NativeModules/OpenCV';
    import CircleWithinCircle from '../assets/svg/CircleWithinCircle';
    
    export default function CameraScreen() {
      const cameraRef = useRef(null);
      const toastRef = useRef(null);
    
      const [cameraPermission, setCameraPermission] = useState(false);
      const [photoAsBase64, setPhotoAsBase64] = useState({
        content: '',
        isPhotoPreview: false,
        photoPath: '',
      });
    
      const checkForBlurryImage = (imageAsBase64) => {
        return new Promise((resolve, reject) => {
          if (Platform.OS === 'android') {
            OpenCV.checkForBlurryImage(
              imageAsBase64,
              (error) => {
                // error handling
              },
              (msg) => {
                resolve(msg);
              },
            );
          } else {
            OpenCV.checkForBlurryImage(imageAsBase64, (error, dataArray) => {
              resolve(dataArray[0]);
            });
          }
        });
      };
    
      const proceedWithCheckingBlurryImage = () => {
        const { content, photoPath } = photoAsBase64;
    
        checkForBlurryImage(content)
          .then((blurryPhoto) => {
            if (blurryPhoto) {
              toastRef.current.show('Photo is blurred!', DURATION.FOREVER);
              repeatPhoto();
            } else {
              toastRef.current.show('Photo is clear!', DURATION.FOREVER);
              setPhotoAsBase64({
                ...photoAsBase64,
                isPhotoPreview: true,
                photoPath,
              });
            }
          })
          .catch((err) => {
            console.log('err', err);
          });
      };
    
      const takePicture = async () => {
        if (cameraRef.current) {
          const options = { quality: 0.5, base64: true };
          const data = await cameraRef.current.takePictureAsync(options);
          setPhotoAsBase64({
            content: data.base64,
            isPhotoPreview: false,
            photoPath: data.uri,
          });
          proceedWithCheckingBlurryImage();
        }
      };
    
      const repeatPhoto = () => {
        setPhotoAsBase64({
          content: '',
          isPhotoPreview: false,
          photoPath: '',
        });
      };
    
      const usePhoto = () => {
        // do something, e.g. navigate
      };
    
      if (photoAsBase64.isPhotoPreview) {
        return (
          <View style={styles.container}>
            <Toast ref={toastRef} position="center" />
            <Image
              source={{ uri: `data:image/png;base64,${photoAsBase64.content}` }}
              style={styles.imagePreview}
            />
            <View style={styles.repeatPhotoContainer}>
              <TouchableOpacity onPress={repeatPhoto}>
                <Text style={styles.photoPreviewRepeatPhotoText}>Repeat photo</Text>
              </TouchableOpacity>
            </View>
            <View style={styles.usePhotoContainer}>
              <TouchableOpacity onPress={usePhoto}>
                <Text style={styles.photoPreviewUsePhotoText}>Use photo</Text>
              </TouchableOpacity>
            </View>
          </View>
        );
      }
    
      return (
        <View style={styles.container}>
          <Camera
            ref={cameraRef}
            style={styles.preview}
            permissionDialogTitle={'Permission to use camera'}
            permissionDialogMessage={
              'We need your permission to use your camera phone'
            }
          >
            <View style={styles.takePictureContainer}>
              <TouchableOpacity onPress={takePicture}>
                <View>
                  <CircleWithinCircle />
                </View>
              </TouchableOpacity>
            </View>
          </Camera>
          <Toast ref={toastRef} position="center" />
        </View>
      );
    }
    
    Login or Signup to reply.
  2. import React, { useState, useRef } from 'react';
    import {
      View,
      Text,
      Platform,
      Image,
      TouchableOpacity,
    } from 'react-native';
    import { RNCamera as Camera } from 'react-native-camera';
    import Toast, { DURATION } from 'react-native-easy-toast';
    
    import styles from '../Styles/Screens/CameraScreen';
    import OpenCV from '../NativeModules/OpenCV';
    import CircleWithinCircle from '../assets/svg/CircleWithinCircle';
    
    export default function CameraScreen() {
      const cameraRef = useRef(null);
    
      const [cameraPermission, setCameraPermission] = useState(false);
      const [photoAsBase64, setPhotoAsBase64] = useState({
        content: '',
        isPhotoPreview: false,
        photoPath: '',
      });
    
      const checkForBlurryImage = (imageAsBase64) => {
        return new Promise((resolve, reject) => {
          if (Platform.OS === 'android') {
            OpenCV.checkForBlurryImage(imageAsBase64, (error) => {
              // error handling
            }, (msg) => {
              resolve(msg);
            });
          } else {
            OpenCV.checkForBlurryImage(imageAsBase64, (error, dataArray) => {
              resolve(dataArray[0]);
            });
          }
        });
      };
    
      const proceedWithCheckingBlurryImage = () => {
        const { content, photoPath } = photoAsBase64;
    
        checkForBlurryImage(content)
          .then((blurryPhoto) => {
            if (blurryPhoto) {
              toastRef.show('Photo is blurred!', DURATION.FOREVER);
              return repeatPhoto();
            }
            toastRef.show('Photo is clear!', DURATION.FOREVER);
            setPhotoAsBase64({ ...photoAsBase64, isPhotoPreview: true, photoPath });
          })
          .catch((err) => {
            console.log('err', err);
          });
      };
    
      const takePicture = async () => {
        if (cameraRef.current) {
          const options = { quality: 0.5, base64: true };
          const data = await cameraRef.current.takePictureAsync(options);
          setPhotoAsBase64({
            content: data.base64,
            isPhotoPreview: false,
            photoPath: data.uri,
          });
          proceedWithCheckingBlurryImage();
        }
      };
    
      const repeatPhoto = () => {
        setPhotoAsBase64({
          content: '',
          isPhotoPreview: false,
          photoPath: '',
        });
      };
    
      const usePhoto = () => {
        // do something, e.g. navigate
      };
    
      const toastRef = useRef(null);
    
      if (photoAsBase64.isPhotoPreview) {
        return (
          <View style={styles.container}>
            <Toast ref={toastRef} position="center" />
            <Image
              source={{ uri: `data:image/png;base64,${photoAsBase64.content}` }}
              style={styles.imagePreview}
            />
            <View style={styles.repeatPhotoContainer}>
              <TouchableOpacity onPress={repeatPhoto}>
                <Text style={styles.photoPreviewRepeatPhotoText}>Repeat photo</Text>
              </TouchableOpacity>
            </View>
            <View style={styles.usePhotoContainer}>
              <TouchableOpacity onPress={usePhoto}>
                <Text style={styles.photoPreviewUsePhotoText}>Use photo</Text>
              </TouchableOpacity>
            </View>
          </View>
        );
      }
    
      return (
        <View style={styles.container}>
          <Camera
            ref={cameraRef}
            style={styles.preview}
            permissionDialogTitle={'Permission to use camera'}
            permissionDialogMessage={'We need your permission to use your camera phone'}
          >
            <View style={styles.takePictureContainer}>
              <TouchableOpacity onPress={takePicture}>
                <View>
                  <CircleWithinCircle />
                </View>
              </TouchableOpacity>
            </View>
          </Camera>
          <Toast ref={toastRef} position="center" />
        </View>
      );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search