Front Facing Camera does not Auto Focus or Manually Focus

我只是一个虾纸丫 提交于 2020-01-15 05:22:33

问题


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:

at RNCamera.m method updateFocusDepth

- (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;
    }

回答1:


IOS has three Focus Modes. You need to use AVCaptureFocusModeContinuousAutoFocus

AVCaptureFocusModeContinuousAutoFocus: The camera continuously autofocuses as needed.

You use the isFocusModeSupported: method to determine whether a device supports a given focus mode, then set the mode using the focusMode property.

react-native-camera will change the focus in two different scenarios (you can set a breakpoint with xcode on this lines):

  1. focusWithMode method will set the focus only if your frontcamera supports isFocusPointOfInterestSupported and AVCaptureFocusModeContinuousAutoFocus

The method will change the focus mode [device setFocusMode:focusMode]; to AVCaptureFocusModeContinuousAutoFocus only if the following condition is returns true

[device isFocusPointOfInterestSupported] && [device isFocusModeSupported:focusMode]

If the condition returns false, there is no autofocus, but the picture may be focused on ExposureMode [device setExposureMode:exposureMode];

  1. updateAutoFocusPointOfInterest changes the focus when the user taps on the screen, based on the x, y coordinates of his touch.

As there are several posts (post 1, post 2, post 3, post 4) on stackoverflow stating that different iphone versions do not support all type of autofocus with the frontcamera, I suggest you to set breakpoints on those line of codes and check the value of isFocusModeSupported and isFocusPointOfInterestSupported



来源:https://stackoverflow.com/questions/55846066/front-facing-camera-does-not-auto-focus-or-manually-focus

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!