Current Issue
While using react-native-camera
on iPads/iPhones, the front-facing camera does not focus properly when scanning barcodes like Code39, Code128, or QR codes. The rear camera works fine, but the front camera fails to focus on the barcode or anything in close proximity.
I have only tested this on iOS and haven't found any solutions to make the front camera focus correctly.
Even if I hold a barcode up to the camera with a gap at the bottom, it still won't attempt to focus on the code and instead stays focused on objects in the background.
I've posted an issue here on GitHub, but wanted to see if anyone else has encountered this problem and found a workaround.
Expected Outcome
I anticipated the camera to recognize the barcode as the main subject, focus on it, read the code, and trigger the onBarCodeRead
function accordingly.
Attempted Solutions
- Disabled
autoFocus
, didn't work as expected. - Tried setting
focusDepth
manually, no improvement. - Set
autoFocusPointOfInterest
to center of screen. - Adjusted the
zoom
level incrementally. - Used
onGoogleVisionBarcodesDetected
for Android fix, no success. - Updated
[email protected]
- Switched to master branch at
react-native-camera@git+https://[email protected]/react-native-community/react-native-camera.git
Steps to Reproduce
- Create a new react-native project.
- Install
react-native-camera
. - Set
to use the front camera.type={RNCamera.Constants.Type.front}
- Ensure
.autoFocus={RNCamera.Constants.AutoFocus.on}
- Implement
.onBarCodeRead={() => alert('barcode found')}
- Try to scan a Code39 / Code128 barcode from an online generator.
- The camera won't focus on the barcode and will remain focused on the background instead.
Software & Versions Used
- iOS: 12.1.4
- react-native-camera: ^2.1.1 / 2.6.0
- react-native: 0.57.7
- react: 16.6.1
Code Snippet
The camera is rendered within a react-native-modal
. Here's the relevant code:
<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
A relevant piece of code can be found in RNCamera.m
at 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];
}];
}
In particular, the section where it checks if
device.position == RNCameraTypeFront
and returns under certain conditions caught my attention.