问题
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):
- focusWithMode method will set the focus only if your frontcamera supports
isFocusPointOfInterestSupported
andAVCaptureFocusModeContinuousAutoFocus
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];
- 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