/* eslint-disable no-console */ import React from 'react'; import { StyleSheet, Text, View, TouchableOpacity, Slider, TouchableWithoutFeedback, Dimensions, } from 'react-native'; // eslint-disable-next-line import/no-unresolved import { RNCamera } from 'react-native-camera'; const flashModeOrder = { off: 'on', on: 'auto', auto: 'torch', torch: 'off', }; const wbOrder = { auto: 'sunny', sunny: 'cloudy', cloudy: 'shadow', shadow: 'fluorescent', fluorescent: 'incandescent', incandescent: 'auto', }; const landmarkSize = 2; export default class CameraScreen extends React.Component { state = { flash: 'off', zoom: 0, autoFocus: 'on', autoFocusPoint: { normalized: { x: 0.5, y: 0.5 }, // normalized values required for autoFocusPointOfInterest drawRectPosition: { x: Dimensions.get('window').width * 0.5 - 32, y: Dimensions.get('window').height * 0.5 - 32, }, }, depth: 0, type: 'back', whiteBalance: 'auto', ratio: '16:9', recordOptions: { mute: false, maxDuration: 5, quality: RNCamera.Constants.VideoQuality['288p'], }, isRecording: false, canDetectFaces: false, canDetectText: false, canDetectBarcode: false, faces: [], textBlocks: [], barcodes: [], }; toggleFacing() { this.setState({ type: this.state.type === 'back' ? 'front' : 'back', }); } toggleFlash() { this.setState({ flash: flashModeOrder[this.state.flash], }); } toggleWB() { this.setState({ whiteBalance: wbOrder[this.state.whiteBalance], }); } toggleFocus() { this.setState({ autoFocus: this.state.autoFocus === 'on' ? 'off' : 'on', }); } touchToFocus(event) { const { pageX, pageY } = event.nativeEvent; const screenWidth = Dimensions.get('window').width; const screenHeight = Dimensions.get('window').height; const isPortrait = screenHeight > screenWidth; let x = pageX / screenWidth; let y = pageY / screenHeight; // Coordinate transform for portrait. See autoFocusPointOfInterest in docs for more info if (isPortrait) { x = pageY / screenHeight; y = -(pageX / screenWidth) + 1; } this.setState({ autoFocusPoint: { normalized: { x, y }, drawRectPosition: { x: pageX, y: pageY }, }, }); } zoomOut() { this.setState({ zoom: this.state.zoom - 0.1 < 0 ? 0 : this.state.zoom - 0.1, }); } zoomIn() { this.setState({ zoom: this.state.zoom + 0.1 > 1 ? 1 : this.state.zoom + 0.1, }); } setFocusDepth(depth) { this.setState({ depth, }); } takePicture = async function() { if (this.camera) { const data = await this.camera.takePictureAsync(); console.warn('takePicture ', data); } }; takeVideo = async function() { if (this.camera) { try { const promise = this.camera.recordAsync(this.state.recordOptions); if (promise) { this.setState({ isRecording: true }); const data = await promise; this.setState({ isRecording: false }); console.warn('takeVideo', data); } } catch (e) { console.error(e); } } }; toggle = value => () => this.setState(prevState => ({ [value]: !prevState[value] })); facesDetected = ({ faces }) => this.setState({ faces }); renderFace = ({ bounds, faceID, rollAngle, yawAngle }) => ( ID: {faceID} rollAngle: {rollAngle.toFixed(0)} yawAngle: {yawAngle.toFixed(0)} ); renderLandmarksOfFace(face) { const renderLandmark = position => position && ( ); return ( {renderLandmark(face.leftEyePosition)} {renderLandmark(face.rightEyePosition)} {renderLandmark(face.leftEarPosition)} {renderLandmark(face.rightEarPosition)} {renderLandmark(face.leftCheekPosition)} {renderLandmark(face.rightCheekPosition)} {renderLandmark(face.leftMouthPosition)} {renderLandmark(face.mouthPosition)} {renderLandmark(face.rightMouthPosition)} {renderLandmark(face.noseBasePosition)} {renderLandmark(face.bottomMouthPosition)} ); } renderFaces = () => ( {this.state.faces.map(this.renderFace)} ); renderLandmarks = () => ( {this.state.faces.map(this.renderLandmarksOfFace)} ); renderTextBlocks = () => ( {this.state.textBlocks.map(this.renderTextBlock)} ); renderTextBlock = ({ bounds, value }) => ( {value} ); textRecognized = object => { const { textBlocks } = object; this.setState({ textBlocks }); }; barcodeRecognized = ({ barcodes }) => this.setState({ barcodes }); renderBarcodes = () => ( {this.state.barcodes.map(this.renderBarcode)} ); renderBarcode = ({ bounds, data, type }) => ( {`${data} ${type}`} ); renderCamera() { const { canDetectFaces, canDetectText, canDetectBarcode } = this.state; const drawFocusRingPosition = { top: this.state.autoFocusPoint.drawRectPosition.y - 32, left: this.state.autoFocusPoint.drawRectPosition.x - 32, }; return ( { this.camera = ref; }} style={{ flex: 1, justifyContent: 'space-between', }} type={this.state.type} flashMode={this.state.flash} autoFocus={this.state.autoFocus} autoFocusPointOfInterest={this.state.autoFocusPoint.normalized} zoom={this.state.zoom} whiteBalance={this.state.whiteBalance} ratio={this.state.ratio} focusDepth={this.state.depth} androidCameraPermissionOptions={{ title: 'Permission to use camera', message: 'We need your permission to use your camera', buttonPositive: 'Ok', buttonNegative: 'Cancel', }} faceDetectionLandmarks={ RNCamera.Constants.FaceDetection.Landmarks ? RNCamera.Constants.FaceDetection.Landmarks.all : undefined } onFacesDetected={canDetectFaces ? this.facesDetected : null} onTextRecognized={canDetectText ? this.textRecognized : null} onGoogleVisionBarcodesDetected={canDetectBarcode ? this.barcodeRecognized : null} > FLIP FLASH: {this.state.flash} WB: {this.state.whiteBalance} {!canDetectFaces ? 'Detect Faces' : 'Detecting Faces'} {!canDetectText ? 'Detect Text' : 'Detecting Text'} {!canDetectBarcode ? 'Detect Barcode' : 'Detecting Barcode'} {} : this.takeVideo.bind(this)} > {this.state.isRecording ? ( ) : ( REC )} {this.state.zoom !== 0 && ( Zoom: {this.state.zoom} )} + - AF : {this.state.autoFocus} SNAP {!!canDetectFaces && this.renderFaces()} {!!canDetectFaces && this.renderLandmarks()} {!!canDetectText && this.renderTextBlocks()} {!!canDetectBarcode && this.renderBarcodes()} ); } render() { return {this.renderCamera()}; } } const styles = StyleSheet.create({ container: { flex: 1, paddingTop: 10, backgroundColor: '#000', }, flipButton: { flex: 0.3, height: 40, marginHorizontal: 2, marginBottom: 10, marginTop: 10, borderRadius: 8, borderColor: 'white', borderWidth: 1, padding: 5, alignItems: 'center', justifyContent: 'center', }, autoFocusBox: { position: 'absolute', height: 64, width: 64, borderRadius: 12, borderWidth: 2, borderColor: 'white', opacity: 0.4, }, flipText: { color: 'white', fontSize: 15, }, zoomText: { position: 'absolute', bottom: 70, zIndex: 2, left: 2, }, picButton: { backgroundColor: 'darkseagreen', }, facesContainer: { position: 'absolute', bottom: 0, right: 0, left: 0, top: 0, }, face: { padding: 10, borderWidth: 2, borderRadius: 2, position: 'absolute', borderColor: '#FFD700', justifyContent: 'center', backgroundColor: 'rgba(0, 0, 0, 0.5)', }, landmark: { width: landmarkSize, height: landmarkSize, position: 'absolute', backgroundColor: 'red', }, faceText: { color: '#FFD700', fontWeight: 'bold', textAlign: 'center', margin: 10, backgroundColor: 'transparent', }, text: { padding: 10, borderWidth: 2, borderRadius: 2, position: 'absolute', borderColor: '#F00', justifyContent: 'center', }, textBlock: { color: '#F00', position: 'absolute', textAlign: 'center', backgroundColor: 'transparent', }, });