Tuesday 30 April 2019

Front Facing Camera does not Auto Focus or Manually Focus

Current Behaviour

I'm using react-native-camera with iPads/iPhones and I use the front-facing camera to scan barcodes (Code39, Code128, QR, etc..) However when using the front-facing camera, it does not focus on the barcode or anything I put mildly close to the camera. The rear camera works absolutely perfectly however the front camera does not.

I have not been able to test android as I'm not building for android purely just iOS. I can't seem to find any information on getting the front camera to focus.

If I was to stand in the background, hold up my Code39 close to the camera but leave a small gap at the bottom, it would not try focus on the card however stay focused on me in the background.

I've also raised an issue here on their GitHub page, but came here to see if anyone has ran in to this before, has a work around etc.

Expected Behaviour

I expect the camera to see the code is taking up a lot more of the screen than I am, focus on it, read the code and proceed to run the code onBarCodeRead

What have I tried to fix it?

  • Disable the autoFocus as this was a fix for Android, no luck here.
  • Manually set the focusDepth.
  • Manually set autoFocusPointOfInterest to center of screen.
  • Change the zoom to 0.2 and slowly increase to the point of where it starts to look silly.
  • Set onGoogleVisionBarcodesDetected to just console.log something as this was another fix for android.
  • Update react-native-camera@2.6.0
  • Update to master branch at react-native-camera@git+https://git@github.com/react-native-community/react-native-camera.git

How can I recreate it?

  • Create new react-native project
  • yarn add react-native-camera / npm install react-native-camera --save
  • set type={RNCamera.Constants.Type.front} to use the front camera.
  • set autoFocus={RNCamera.Constants.AutoFocus.on} (It's on by default anyway, this just ensures it.
  • set onBarCodeRead={() => alert('barcode found')}
  • Try to scan a Code39 / Code128 - (creatable here)
  • Try to scan it and you'll find the camera will not focus on it however stay focused on the background. This is also true if you cover the camera with your finger, when you pull your finger away you expect the camera to be out of focus to the background and try and re-focus. This is not the case, it will stay focused at a medium / long distance.

Software Used & Versions

  • iOS: 12.1.4
  • react-native-camera: ^2.1.1 / 2.6.0
  • react-native: 0.57.7
  • react: 16.6.1

Code

I render the camera in a react-native-modal and I've put my code below.

<RNCamera 
  style={styles.camera}
  type={RNCamera.Constants.Type.front}
  flashMode={RNCamera.Constants.FlashMode.off}
  autoFocus={RNCamera.Constants.AutoFocus.on}
  captureAudio={false}
  onBarCodeRead={(barcode) => {
    if (this.state.isModalVisible) {
      this.setState({
        isModalVisible : false
      }, () => this.captureQR(barcode.data));
    }
}}>

Relevant Package Code

I found some code that seems relevant:

/react-native-camera/blob/master/ios/RN/RNCamera.m - L275-L300

- (void)updateFocusDepth
{
    AVCaptureDevice *device = [self.videoCaptureDeviceInput device];
    NSError *error = nil;

    if (device == nil || self.autoFocus < 0 || device.focusMode != RNCameraAutoFocusOff || device.position == RNCameraTypeFront) {
        return;
    }

    if (![device respondsToSelector:@selector(isLockingFocusWithCustomLensPositionSupported)] || ![device isLockingFocusWithCustomLensPositionSupported]) {
        RCTLogWarn(@"%s: Setting focusDepth isn't supported for this camera device", __func__);
        return;
    }

    if (![device lockForConfiguration:&error]) {
        if (error) {
            RCTLogError(@"%s: %@", __func__, error);
        }
        return;
    }

    __weak __typeof__(device) weakDevice = device;
    [device setFocusModeLockedWithLensPosition:self.focusDepth completionHandler:^(CMTime syncTime) {
        [weakDevice unlockForConfiguration];
    }];
}

More specifically just this section here:

If device.position == RNCameraTypeFront it will just return providing it doesn't meet any of the other criteria.

    if (device == nil || self.autoFocus < 0 || device.focusMode != RNCameraAutoFocusOff || device.position == RNCameraTypeFront) {
        return;
    }



from Front Facing Camera does not Auto Focus or Manually Focus

No comments:

Post a Comment