React Native Custom Camera Preview with Crop image and Toggle Camera
June 17, 2021
Camera.js (Componet)
import React, {useRef,useState} from 'react';
import {RNCamera} from 'react-native-camera';
import Icon from 'react-native-vector-icons/dist/MaterialIcons';
import {TouchableOpacity, StyleSheet,View,Image} from 'react-native';
import ImagePicker from 'react-native-image-crop-picker';
const Camera = ({poseimage,ImagePicCallBack,Crop}) => {
const Refcamera = useRef(null);
const [FrontCam, setFrontCam] = useState(true)
const PickImage = async () => {
if (Refcamera.current) {
let options = {
quality: .85,
skipProcessing:true,
pauseAfterCapture: true,
fixOrientation: false
}
try {
const data = await Refcamera.current.takePictureAsync(options);
if(!Crop){
ImagePicker.openCropper({
path: data.uri,
width: 400,
height: 400,
cropperToolbarTitle:'Edit Image',
compressImageQuality: 0.8,
freeStyleCropEnabled:true,
cropping: true
}).then(image => {
const userSourceImg = {
uri: image.path,
type: 'image/*'
}
ImagePicCallBack(userSourceImg)
}).catch(err=>{
console.info(err)
})
}else{
console.info(data)
ImagePicCallBack(data)
}
} catch (err) {
console.info('Error', 'Failed to take picture: ' + (err.message || err));
return false;
}
}
}
return (
<RNCamera
ref={Refcamera}
captureAudio={false}
style={{flex: 1}}
type={FrontCam?RNCamera.Constants.Type.front:RNCamera.Constants.Type.back}
androidCameraPermissionOptions={{
title: 'Permission to use camera',
message: 'We need your permission to use your camera',
buttonPositive: 'Ok',
buttonNegative: 'Cancel',
}}>
<View style={styles.btnAlignment}>
<View style={{width:30}}/>
<TouchableOpacity
activeOpacity={0.5}
onPress={()=>PickImage()}
>
<Icon name="camera" size={50} color="#fff" />
</TouchableOpacity>
<TouchableOpacity
activeOpacity={0.5}
onPress={()=>setFrontCam(!FrontCam)}
>
<Icon
name="flip-camera-ios" size={30} color="#fff" />
</TouchableOpacity>
</View>
{poseimage&&
<View style={styles.PoseView}>
<Image
borderRadius={10}
style={{flex:1,resizeMode:'cover'}}
source={{
uri: poseimage,
}}
/>
</View>
}
</RNCamera>
)
}
const styles = StyleSheet.create({
btnAlignment: {
flex: 0,
flexDirection: 'row',
justifyContent: 'space-around',
alignItems:'center',
backgroundColor: 'rgba(0,0,0,0.2)',
position: 'absolute',
bottom: 0,
height: 150,
left: 0,
right: 0,
},
PoseView: {
flex: 0,
position: 'absolute',
width: 125,
height: 210,
top: 40,
right: 10,
},
});
export default Camera;
Home.js
import React from 'react'
import styled from 'styled-components/native';
import { StyleSheet,Dimensions,Image } from 'react-native';
import Camera from '../../Componets/Camera';
const {width,height}=Dimensions.get('window');
const ImagePose='https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRJeRuZsdRkBuGFueGIwddVqCuVijek3zD9oASxgqdAp_4epFP52jPEzP9DJGyEQotkWwI&usqp=CAU';
const Home = ({navigation}) => {
const ImagePicCallBack=(data)=>{
navigation.navigate('PreViewPage', { ImageData: data ,PoseImage:ImagePose})
}
return (
<MainView>
<StatusBar
translucent={true}
barStyle={'light-content'}
backgroundColor={'transparent'}
/>
<Camera
captureAudio={false}
poseimage={ImagePose}
Crop={true}
ImagePicCallBack={(Imagedata)=>ImagePicCallBack(Imagedata)}
/>
</MainView>
)
}
const MainView = styled.View`
flex: 1;
`;
const MainViewUI = styled.View`
padding-top: 40px;
`;
const MainViewSafeUI = styled.SafeAreaView`
margin: 20px;
`;
const SearchBarDotText = styled.View`
flex-direction: row;
align-items: center;
`;
const GreenDot = styled.View`
height: 10px;
width:10px;
margin: 0px 10px 0px 0px;
background-color: #4caf50;
border-radius: 5px;
`;
const SearchBarView=styled.View`
flex-direction: row;
margin: 15px 0px 0px 0px;
padding: 15px;
background-color: white;
justify-content: space-between;
align-items: center;
`;
const TextInput=styled.Text`
font-weight: 500;
font-size: 14px;
`;
const StatusBar=styled.StatusBar``;
export default Home