I'm using Camera that comes from expo package and I'm having trouble with camera preview distortion. The preview makes images appear wider in landscape view and thinner in portrait view. I've tried to use a prepareRatio function to find the supported ratio of the current phone and then set the ratio prop to that ratio. However, this did not fix the distortion.
Relevant Code:
camera.page.js:
import React from 'react';
import { View, Text } from 'react-native';
import { Camera } from 'expo-camera';
import * as Permissions from 'expo-permissions'
import { Platform } from 'react-native';
import styles from './styles';
import Toolbar from './toolbar.component';
const DESIRED_RATIO = "18:9";
export default class CameraPage extends React.Component {
camera = null;
state = {
hasCameraPermission: null,
};
async componentDidMount() {
const camera = await Permissions.askAsync(Permissions.CAMERA);
const audio = await Permissions.askAsync(Permissions.AUDIO_RECORDING);
const hasCameraPermission = (camera.status === 'granted'&& audio.status === 'granted');
this.setState({ hasCameraPermission });
};
prepareRatio = async () => {
if (Platform.OS === 'android'&& this.cam) {
const ratios = await this.cam.getSupportedRatiosAsync();
// See if the current device has your desired ratio, otherwise get the maximum supported one
// Usually the last element of "ratios" is the maximum supported ratio
const ratio = ratios.find((ratio) => ratio === DESIRED_RATIO) || ratios[ratios.length - 1];
this.setState({ ratio });
}
}
render() {
const { hasCameraPermission } = this.state;
if (hasCameraPermission === null) {
return <View />;
} else if (hasCameraPermission === false) {
return <Text>Access to camera has been denied.</Text>;
}
return (
<React.Fragment>
<View>
<Camera
ref={camera => this.camera = camera}
onCameraReady={this.prepareRatio}
ratio={this.state.ratio}
style={styles.preview}
/>
</View>
<Toolbar/>
</React.Fragment>
);
};
};
styles.js:
import { StyleSheet, Dimensions } from 'react-native';
const { width: winWidth, height: winHeight } = Dimensions.get('window');
export default StyleSheet.create({
preview: {
height: winHeight,
width: winWidth,
position: 'absolute',
left: 0,
top: 0,
right: 0,
bottom: 0,
paddingBottom: 1000,
},
alignCenter: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
bottomToolbar: {
width: winWidth,
position: 'absolute',
height: 100,
bottom: 0,
},
captureBtn: {
width: 60,
height: 60,
borderWidth: 2,
borderRadius: 60,
borderColor: "#FFFFFF",
},
captureBtnActive: {
width: 80,
height: 80,
},
captureBtnInternal: {
width: 76,
height: 76,
borderWidth: 2,
borderRadius: 76,
backgroundColor: "red",
borderColor: "transparent",
},
});
Am I going about this problem incorrectly?