Crop bounding boxes from React Native Camera

Viewed 115

I have a react native application which uses react native camera to detect the faces and do some process on that. So, when the face is detected I am showing bounding boxes over the camera and now I want that bounding box to be cropped. So, the cropped image will only have the detected face.

From RNCamera I'm getting bounds origin and height width of generated bounding box, and with ImageEditor I'm cropping that particular box(face) from image. But the cropped image is wrong. It is not cropping the correct face. The cropped image contains irrelevant things on image.

So, what I want is what I'm getting on bounding box that needs to be cropped as different image. I have tried many changes like setting aspect ratio, changing the origins and height width of image. But none of them seems to work. Any help would be appreciated. Below is my code.

return (
      <RNCamera
        ref={ref => {
          this.camera = ref;
        }}
        style={{
          height: '100%'
        }}
        type={this.state.type}
        flashMode={this.state.flash}
        autoFocus={this.state.autoFocus}
        zoom={this.state.zoom}
        whiteBalance={this.state.whiteBalance}
        ratio={this.state.ratio}
        focusDept3={this.state.depth}
        trackingEnabled
        androidCameraPermissionOptions={{
          title: 'Permission to use camera',
          message: 'We need your permission to use your camera',
          buttonPositive: 'Ok',
          buttonNegative: 'Cancel',
        }}
        faceDetectionMode={RNCamera.Constants.FaceDetection.Mode.fast}
        onFacesDetected={canDetectFaces ? this.takeFacePicture : null}
        onTextRecognized={canDetectText ? this.textRecognized : null}
        onGoogleVisionBarcodesDetected={canDetectBarcode ? this.barcodeRecognized : null}
        googleVisionBarcodeType={RNCamera.Constants.GoogleVisionBarcodeDetection.BarcodeType.ALL}
        googleVisionBarcodeMode={
          RNCamera.Constants.GoogleVisionBarcodeDetection.BarcodeMode.ALTERNATE
        }
      >
)
takeFacePicture = async function (faces) {
    if (this.camera) {
      const data = await this.camera.takePictureAsync({ quality: 1, base64: true });
      const cropData = { 
        offset: {
         x: faces[0]["bounds"]['origin']["x"],
         y: faces[0]["bounds"]['origin']["y"] 
        }, 
        size: { 
          width: faces[0]["bounds"]['size']["width"],
          height: faces[0]["bounds"]['size']["height"]
        }
      };

      console.log("======>>>>>>>>>>",cropData)

      ImageEditor.cropImage(data.uri, cropData).then((url) => {
        ImgToBase64.getBase64String(url)
          .then(base64String => console.log("cropped image base64==", base64String))
          .catch(err => console.log("error making base64", err));
      })
      
    }
  }

Scanned image: Scanned image

Current cropped image from library: Current cropped image from library

Required image: Required image

1 Answers

Finally, I have found the solution.

I have to resize my captured image from the RNCamera and then apply the login of bounding box cropping. A big thanks to ImageResizer. Below is the working code to crop the required image

ImageResizer.createResizedImage(uri, windowWidth, windowHeight, 'JPEG', 50, 0, null)
      .then(response => {
          const cropData = {
            offset: {
              x: faces[0]["bounds"]['origin']["x"],
              y: faces[0]["bounds"]['origin']["y"]
            },
            size: {
              width: faces[0]["bounds"]['size']["width"],
              height: faces[0]["bounds"]['size']["height"]
            },
          };

          ImageEditor.cropImage(response.uri, cropData).then((url) => {
            ImgToBase64.getBase64String(url)
              .then(base64String => console.log(base64String))
              .catch(err => console.log("error making base64", err));
          })
      })
      .catch(err => {
        console.log("err", err)
      });

Related