How to play recording through the speaker in react native expo av - react-native

I'm trying to make a voice memo component for my app using expo-av. I've figured out how to create the recording but when playing it, it only plays through the earpiece speaker. Is there a way I can playback the recording through the main phone speakers? I haven't tried testing this on android but for iPhone the audio only plays back through the earphone speaker. Thank you.
import React from 'react';
import { Button, StyleSheet, Text, View, TouchableOpacity } from 'react-native';
import { Audio } from 'expo-av';
import * as Sharing from 'expo-sharing';
import { MaterialCommunityIcons } from '#expo/vector-icons';
import AppText from './AppText';
import Screen from './Screen';
export default function AppVoice() {
const [recording, setRecording] = React.useState();
const [recordings, setRecordings] = React.useState([]);
const [message, setMessage] = React.useState("");
async function startRecording() {
try {
const permission = await Audio.requestPermissionsAsync();
if (permission.status === "granted") {
await Audio.setAudioModeAsync({
allowsRecordingIOS: true,
playsInSilentModeIOS: true,
});
const { recording } = await Audio.Recording.createAsync(
Audio.RECORDING_OPTIONS_PRESET_HIGH_QUALITY
);
setRecording(recording);
} else {
setMessage("Please grant permission to app to access microphone");
}
} catch (err) {
console.error('Failed to start recording', err);
}
}
async function stopRecording() {
setRecording(undefined);
await recording.stopAndUnloadAsync();
let updatedRecordings = [...recordings];
const { sound, status } = await recording.createNewLoadedSoundAsync();
updatedRecordings.push({
sound: sound,
duration: getDurationFormatted(status.durationMillis),
file: recording.getURI()
});
setRecordings(updatedRecordings);
}
function getDurationFormatted(millis) {
const minutes = millis / 1000 / 60;
const minutesDisplay = Math.floor(minutes);
const seconds = Math.round((minutes - minutesDisplay) * 60);
const secondsDisplay = seconds < 10 ? `0${seconds}` : seconds;
return `${minutesDisplay}:${secondsDisplay}`;
}
function getRecordingLines() {
return recordings.map((recordingLine, index) => {
return (
<View key={index} style={styles.row}>
<Text style={styles.fill}>Recording {index + 1} - {recordingLine.duration}</Text>
<Button style={styles.button} onPress={() => recordingLine.sound.replayAsync()} title="Play"></Button>
<Button style={styles.button} onPress={() => Sharing.shareAsync(recordingLine.file)} title="Share"></Button>
</View>
);
});
}
return (
<Screen style={{flex:1, backgroundColor:'black'}}>
<View style={styles.container}>
<View style={styles.recorder}>
<TouchableOpacity style={{position:'absolute', left:10}}>
<MaterialCommunityIcons name="microphone" size={24} color="black" />
</TouchableOpacity>
<AppText style={{color:'black', textAlign:'center'}}>Voice Memo</AppText>
<TouchableOpacity onPress={recording ? stopRecording : startRecording} style={{position:'absolute', right:10}}>
{recording ? <MaterialCommunityIcons name="pause" size={28} color="black" /> : <MaterialCommunityIcons name="record-circle-outline" size={28} color="red" />}
</TouchableOpacity>
</View>
<View style={{flex:1}}>
{getRecordingLines()}
</View>
</View>
</Screen>
);
}
const styles = StyleSheet.create({
recorder: {
width:300,
backgroundColor:'white',
height:50,
borderRadius: 100,
justifyContent:'center'
},
container:{
flex:1,
},
row: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
},
fill: {
flex: 1,
margin: 16,
color:'white'
},
button: {
margin: 16
}
});

I don't know how I figured it out but what you need to do is when recording you need to have the "allowRecordingIOS" to true and when stopping the recording you have to set it to false. Here's the updated code:
import React from 'react';
import { Button, StyleSheet, Text, View, TouchableOpacity } from 'react-native';
import { Audio } from 'expo-av';
import * as Sharing from 'expo-sharing';
import { MaterialCommunityIcons } from '#expo/vector-icons';
import AppText from './AppText';
import Screen from './Screen';
export default function AppVoice() {
const [recording, setRecording] = React.useState();
const [recordings, setRecordings] = React.useState([]);
const [message, setMessage] = React.useState("");
async function startRecording() {
try {
const permission = await Audio.requestPermissionsAsync();
if (permission.status === "granted") {
await Audio.setAudioModeAsync({
allowsRecordingIOS: true,
playsInSilentModeIOS: true,
});
const { recording } = await Audio.Recording.createAsync(
Audio.RECORDING_OPTIONS_PRESET_HIGH_QUALITY
);
setRecording(recording);
} else {
setMessage("Please grant permission to app to access microphone");
}
} catch (err) {
console.error('Failed to start recording', err);
}
}
async function stopRecording() {
setRecording(undefined);
await recording.stopAndUnloadAsync();
await Audio.setAudioModeAsync({
allowsRecordingIOS: false,
playsInSilentModeIOS: true,
});
let updatedRecordings = [...recordings];
const { sound, status } = await recording.createNewLoadedSoundAsync();
updatedRecordings.push({
sound: sound,
duration: getDurationFormatted(status.durationMillis),
file: recording.getURI()
});
setRecordings(updatedRecordings);
}
function getDurationFormatted(millis) {
const minutes = millis / 1000 / 60;
const minutesDisplay = Math.floor(minutes);
const seconds = Math.round((minutes - minutesDisplay) * 60);
const secondsDisplay = seconds < 10 ? `0${seconds}` : seconds;
return `${minutesDisplay}:${secondsDisplay}`;
}
function getRecordingLines() {
return recordings.map((recordingLine, index) => {
return (
<View key={index} style={styles.row}>
<Text style={styles.fill}>Recording {index + 1} - {recordingLine.duration}</Text>
<Button style={styles.button} onPress={() => recordingLine.sound.replayAsync()} title="Play"></Button>
<Button style={styles.button} onPress={() => Sharing.shareAsync(recordingLine.file)} title="Share"></Button>
</View>
);
});
}
return (
<Screen style={{flex:1, backgroundColor:'black'}}>
<View style={styles.container}>
<View style={styles.recorder}>
<TouchableOpacity style={{position:'absolute', left:10}}>
<MaterialCommunityIcons name="microphone" size={24} color="black" />
</TouchableOpacity>
<AppText style={{color:'black', textAlign:'center'}}>Voice Memo</AppText>
<TouchableOpacity onPress={recording ? stopRecording : startRecording} style={{position:'absolute', right:10}}>
{recording ? <MaterialCommunityIcons name="pause" size={28} color="black" /> : <MaterialCommunityIcons name="record-circle-outline" size={28} color="red" />}
</TouchableOpacity>
</View>
<View style={{flex:1}}>
{getRecordingLines()}
</View>
</View>
</Screen>
);
}
const styles = StyleSheet.create({
recorder: {
width:300,
backgroundColor:'white',
height:50,
borderRadius: 100,
justifyContent:'center'
},
container:{
flex:1,
},
row: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
},
fill: {
flex: 1,
margin: 16,
color:'white'
},
button: {
margin: 16
}
});

Related

React Native: Camera from "expo-camera" stop running when face is not ever detected

I am newer for using react-native, and wanna try to create a camera with filter. I'm blocked in step to recognize face. Have success to draw rectangle when face detected, but the problem is once it goes out of detection. The camera stop running as it fixes on the last real-time capture
Here is my code:
import { useState, useEffect, useRef } from 'react'
import { Camera } from 'expo-camera'
import * as MediaLibrary from 'expo-media-library'
import { Text, StyleSheet, View, TouchableOpacity } from 'react-native'
import Button from './Button'
import { Ionicons } from '#expo/vector-icons'
import * as FaceDetector from 'expo-face-detector'
export default function PCamera() {
const cameraRef = useRef(undefined)
const [faceDetected, setFaceDetected] = useState([])
const [lastImage, setImage] = useState(undefined)
const [hasUsePermssion, setUsePermission] = useState(false)
const [type, switchToType] = useState(Camera.Constants.Type.front)
const takePicture = async () => {
if (cameraRef) {
try {
const options = {
quality: 1,
base64: true,
exif: false,
}
const data = await cameraRef.current.takePictureAsync(options)
setImage(data.uri)
console.log(data)
} catch (err) {
console.error(err)
}
}
}
const swithMode = () => {
switchToType(
type === Camera.Constants.Type.front
? Camera.Constants.Type.back
: Camera.Constants.Type.front
)
}
const handleFacesDetected = ({ faces }) => {
setFaceDetected(faces)
}
useEffect(() => {
;(async () => {
const { status } = await Camera.requestCameraPermissionsAsync()
if (status === 'granted') {
setUsePermission(true)
}
})()
}, [])
if (hasUsePermssion === null) {
return <View />
}
if (hasUsePermssion === false) {
return <Text>No access to camera</Text>
}
return (
<View style={styles.cameraContainer}>
<View style={styles.overlay}>
<Camera
ref={cameraRef}
style={styles.camera}
type={type}
onFacesDetected={handleFacesDetected}
faceDetectorSettings={{
mode: FaceDetector.FaceDetectorMode.fast,
detectLandmarks: FaceDetector.FaceDetectorLandmarks.all,
runClassifications:
FaceDetector.FaceDetectorClassifications.none,
minDetectionInterval: 100,
tracking: true,
}}
>
{faceDetected.length > 0 &&
faceDetected.map((face) => (
<View
key={face.faceID}
style={{
position: 'absolute',
borderWidth: 2,
borderColor: 'red',
left: face.bounds.origin.x,
top: face.bounds.origin.y,
width: face.bounds.size.width,
height: face.bounds.size.height,
}}
/>
))}
</Camera>
</View>
<View style={styles.optionsContainer}>
<View>
<TouchableOpacity onPress={swithMode}>
<Text>
<Ionicons
name="camera-reverse-outline"
size={24}
color="black"
/>
</Text>
</TouchableOpacity>
</View>
<Button
icon="camera"
title="Take Photo"
onPress={takePicture}
style={styles.button}
/>
<View>
<Text>...</Text>
</View>
</View>
</View>
)}
const styles = StyleSheet.create({
cameraContainer: {flex: 1,
},
overlay: {
flex: 6,
borderBottomStartRadius: 75,
borderBottomEndRadius: 75,
overflow: 'hidden',
},
camera: {
flex: 1,
},
optionsContainer: {
flex: 1,
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center',
},
})
N.B: Don't take care of the Button, it's a custom component and works well

How do you get 1 specific value from a prop in expo?

I've been trying to pass up this prop from CameraButton.js file that gives the UI of an image that was taken but whenever I activate the prop in the AddPost.js, it gives me all the values but when I try to get the singular value of the image like using console.log(props.route.params.image) and gives error undefined is not an object
enter image description here
but it works perfectly when export default function console.log(props.route.params) and shows
enter image description here
AddPost.JS
import { useNavigation } from "#react-navigation/core";
import React from 'react'
import {useState} from "react";
import { View, TextInput, Button } from 'react-native'
export default function AddPost(props) {
console.log(props);
const navigation = useNavigation();
const [caption, setCaption] = useState("")
const uploadImage = async () => {
const response = await fetch(uri)
}
return (
<View style={{flex: 1}}>
<TextInput
placeholder="Whats on your mind Edgers navars"
onChangeText={(caption) => setCaption(caption)}
/>
<Button title = "Take A Photo" onPress={() => navigation.navigate("CameraButton")}
/>
<Button title = "Save" onPress={() => uploadImage()}
/>
</View>
)
}
CameraButton.Js
import { Camera, CameraType } from 'expo-camera';
import { useNavigation } from "#react-navigation/core";
import { useState } from 'react';
import { Button, StyleSheet, Text, TouchableOpacity, View, Image } from 'react-native';
import * as ImagePicker from 'expo-image-picker';
export default function App() {
const navigation = useNavigation();
const [type, setType] = useState(Camera.Constants.Type.back)
const [permission, requestPermission] = Camera.useCameraPermissions();
const [image, setImage] = useState(null);
const [camera, setCamera] = useState(null);
const takePicture = async () => {
if(camera){
const data = await camera.takePictureAsync(null);
setImage(data.uri);
}
}
if (!permission) {
// Camera permissions are still loading
return <View />;
}
if (!permission.granted) {
// Camera permissions are not granted yet
return (
<View style={styles.container}>
<Text style={{ textAlign: 'center' }}>
We need your permission to show the camera
</Text>
<Button onPress={requestPermission} title="grant permission" />
</View>
);
}
function toggleCameraType() {
setType((current) => (
current === Camera.Constants.Type.back ? Camera.Constants.Type.front : Camera.Constants.Type.back
));
}
// No permissions request is necessary for launching the image library
let openImagePickerAsync = async () => {
let permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync();
if (permissionResult.granted === false) {
alert("Permission to access camera roll is required!");
return;
}
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
aspect: [4, 3],
quality: 1,
});
if (!result.cancelled) {
setImage(result.uri);
}
}
return (
<View style={styles.container}>
<Camera ref={ref => setCamera(ref)} style={styles.camera} type={type}>
<View style={styles.buttonContainer}>
<TouchableOpacity
style={styles.button}
onPress={toggleCameraType}>
<Text style={styles.text}>Flip Camera</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() => takePicture()}>
<Text style={styles.text}>Take Picture</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={openImagePickerAsync}>
<Text style={styles.text}>Choose Picture</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() => navigation.navigate('AddPost', {image})}>
<Text style={styles.text}>Save Picture</Text>
</TouchableOpacity>
</View>
</Camera>
{image &&<Image source={{uri: image}}style={styles.camera}/>}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
camera: {
flex: 1,
},
buttonContainer: {
flex: 1,
flexDirection: 'row',
backgroundColor: 'transparent',
margin: 64,
},
button: {
flex: 1,
alignSelf: 'flex-end',
alignItems: 'center',
},
text: {
fontSize: 24,
fontWeight: 'bold',
color: 'white',
},
});
You have to get the uri from the route object.
const response = await fetch(props.route.params?.image)
In you file CameraButton.js set the navigation for this:
<TouchableOpacity
style={styles.button}
onPress={() => navigation.navigate('AddPost', {
image: image
})}>
<Text style={styles.text}>Save Picture</Text>
</TouchableOpacity>
Be sure that the state image contains only the uri and not and object
Try props[0].route.params.image.

I am creating a React native web view

My file name is talesrunner23 and splash.png file is in ASSETS, but when you run it, it says it can't be found
<Image source={require('/talesrunner23/assets/splash.png/')}They say I'm wrong here
please help me I'm a beginner, so I have to write down all the codes
please please
I don't know at all
*import React, { useRef, useState, useCallback, useEffect } from 'react';
import {
View,
BackHandler,
Platform,
StyleSheet,
ActivityIndicator,
} from 'react-native';
import { WebView } from 'react-native-webview';
const DELAY_BEFORE_WEBVIEW = 10; // <--- seconds before webview load
export default function App() {
// ref
const webView = useRef();
// callbacks
const handleBack = useCallback(() => {
if (canGoBack && webView.current) {
webView.current.goBack();
return true;
}
return false;
`enter code here`;
}, [canGoBack]);
// effects
useEffect(() => {
BackHandler.addEventListener('hardwareBackPress', handleBack);
return () => {
BackHandler.removeEventListener('hardwareBackPress', handleBack);
};
}, [handleBack]);
useEffect(() => {
setTimeout(() => {
setIsLoading(false);
}, 30 * DELAY_BEFORE_WEBVIEW);
}, []);
// states
const [canGoBack, setCanGoBack] = useState(false);
const [isLoading, setIsLoading] = useState(true);
return (
<View style={styles.container}>
<WebView
ref={webView}
source={{ uri: 'https://www.talesrunnerbestguild.co.kr/' }}
style={styles.webView}
onLoadProgress={(event) => setCanGoBack(event.nativeEvent.canGoBack)}
/>
{isLoading && <CenterLoader />}
</View>
);
}
const CenterLoader = () => (
<View style={styles.loaderContainer}>
<Image source={require('/talesrunner23/assets/splash.png/')}
style={{height:100,width:100}}/>
</View>
);
const styles = StyleSheet.create({
container: { flex: 1 },
loaderContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
position: 'absolute',
width: '100%',
height: '100%',
backgroundColor:'white' // <-- comment this to show webview while loading
},
webView:
Platform.OS === 'ios'
? { marginTop: 30, marginBottom: 40 }
: { marginTop: 30 },
});
You will not want to require but import the Image source at the top. Here is a quick example I made in a sandbox: https://codesandbox.io/s/image-example-c4irqo?file=/src/App.js
import Cat from "./cat.jpeg";
function App() {
return (
<View style={styles.app}>
<View style={styles.header}>
<Image
accessibilityLabel="Cat"
source={Cat}
resizeMode="contain"
style={styles.logo}
/>
<Text style={styles.title}>Image Example</Text>
</View>
</View>
);
}

Error in uploading image with 'react-native-image-picker' library

I am creating an android application and I need to use the react-native-image-picker library but it is showing some error, the error is:
[Unhandled promise rejection: TypeError: null is not an object (evaluating '_reactNative.NativeModules.ImagePickerManager.launchImageLibrary')]
I have tried everything like changing to different versions as well, also I have used expo-image-picker which does not show an error while fetching an image from android but gives an error when uploading it to firebase.
Please help, I have been frustrated with this error.
import {
View,
Text,
Image,
StyleSheet,
KeyboardAvoidingView,
TouchableOpacity,
ActivityIndicator
} from "react-native";
import React, { useState } from "react";
import { TextInput, Button } from "react-native-paper";
import ImagePicker, { launchImageLibrary } from "react-native-image-picker";
import storage from "#react-native-firebase/storage";
import auth from '#react-native-firebase/auth';
import firestore, {getStorage, ref, uploadBytes} from '#react-native-firebase/firestore';
export default function SignUp({ navigation }) {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [image, setImage] = useState(null);
const [shownext, setShownext] = useState(false);
const [loading, setLoading] = useState(false);
if (loading) {
return <ActivityIndicator size='large' />
}
const userSignUp = async () => {
setLoading(true)
if (!email || !password || !image || !name) {
alert('fill all details correctly')
return false;
}
try {
const result = await auth().createUserWithEmailAndPassword(email, password);
firestore().collection('users').doc(result.user.uid).set({
name: name,
email: result.user.email,
uid: result.user.uid,
pic:image
})
setLoading(false)
}catch (err) {
alert('something went wrong from your side')
}
}
const pickImageAndUpload = () => {
console.log(1);
launchImageLibrary({ puality: 0.5 }, async (fileobj) => {
console.log(2);
console.log(fileobj);
const uploadTask = storage().ref().child(`/userprofilepic/${Date.now()}`).putFile(fileobj.uri);
uploadTask.on(
"state_changed",
(snapshot) => {
const progress =
(snapshot.bytesTransferred / snapshot.totalBytes) * 100;
if (progress == 100) alert("image uploaded");
},
(error) => {
alert("error uploading image");
},
() => {
getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
setImage(downloadURL);
});
}
);});
};
return (
<KeyboardAvoidingView behavior="position" style={{ alignItems: "center" }}>
<View style={styles.box1}>
<Text style={styles.text}>Welcome to chatapplication</Text>
<Image style={styles.img} source={require("../assets/wa-logo.png")} />
</View>
{!shownext && (
<>
<TextInput
style={{ width: 330, marginTop: 50, marginBottom: 30 }}
label="Email"
value={email}
mode="outlined"
onChangeText={(text) => setEmail(text)}
/>
<TextInput
style={{ width: 330, marginBottom: 30 }}
label="Password"
value={password}
mode="outlined"
onChangeText={(text) => setPassword(text)}
secureTextEntry
/>
</>
)}
{shownext ? (
<>
<TextInput
style={{ width: 330, marginTop: 50, marginBottom: 30 }}
label="Name"
value={name}
mode="outlined"
onChangeText={(text) => setName(text)}
/>
<Button
style={{ marginBottom: 30 }}
mode="contained"
onPress={() => { pickImageAndUpload() }}
>
Upload Profile Pic
</Button>
<Button
disabled={image?false:true}
mode="contained"
onPress={() => { userSignUp() }}>
SignUp
</Button>
</>
) : (
<Button
// disabled={email&&password?false:true}
mode="contained"
onPress={() => {
setShownext(true);
}}
>
Next
</Button>
)}
<TouchableOpacity onPress={() => navigation.goBack()}>
<Text style={{ margin: 10, textAlign: "center", fontSize: 18 }}>
Already have an account?
</Text>
</TouchableOpacity>
</KeyboardAvoidingView>
);
}
const styles = StyleSheet.create({
text: {
fontSize: 22,
color: "green",
margin: 20,
},
img: {
width: 200,
height: 200,
},
box1: {
alignItems: "center",
},
});

how to capture image using expo-camera in react native

I am new to react-native. I have created an app. but now I want to Capture Image from this app. I have got the code from expo website But the problem is This code only open camera. I want to capture An Image Through That camera. So if it is possible please help me..
here is my code
import React, { useState, useEffect } from 'react';
import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
import { Camera } from 'expo-camera';
import { Ionicons } from '#expo/vector-icons';
export default function App({navigation}) {
const [hasPermission, setHasPermission] = useState(null);
const [type, setType] = useState(Camera.Constants.Type.back);
useEffect(() => {
(async () => {
const { status } = await Camera.requestPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
if (hasPermission === null) {
return <View />;
}
if (hasPermission === false) {
return <Text>No access to camera</Text>;
}
return (
<View style={styles.container}>
<View style={styles.header}>
<Ionicons style={{paddingLeft:20}} name="arrow-back" size={40}
color="black" onPress={() => navigation.navigate("OtherInfo")} />
<Text style={{fontSize:20, paddingLeft: 70, paddingTop: 10}}>Get Image</Text>
</View>
<Camera style={styles.camera} type={type}>
<View style={styles.buttonContainer}>
<TouchableOpacity
style={styles.button}
onPress={() => {
setType(
type === Camera.Constants.Type.back
? Camera.Constants.Type.front
: Camera.Constants.Type.back
);
}}>
<Text style={styles.text}> Flip </Text>
</TouchableOpacity>
</View>
</Camera>
</View>
);
}
const styles = StyleSheet.create({
camera:{
height:500
},
header:{
flexDirection: 'row'
}
});
Here is the working Example of the small app which takes the picture from Camera as well as Gallary and shows it to after it is clicked or selected
Working App: Expo Snack
import React, { useState, useEffect } from 'react';
import { StyleSheet, Text, View, Button, Image } from 'react-native';
import { Camera } from 'expo-camera';
import * as ImagePicker from 'expo-image-picker';
export default function Add({ navigation }) {
const [cameraPermission, setCameraPermission] = useState(null);
const [galleryPermission, setGalleryPermission] = useState(null);
const [camera, setCamera] = useState(null);
const [imageUri, setImageUri] = useState(null);
const [type, setType] = useState(Camera.Constants.Type.back);
const permisionFunction = async () => {
// here is how you can get the camera permission
const cameraPermission = await Camera.requestCameraPermissionsAsync();
setCameraPermission(cameraPermission.status === 'granted');
const imagePermission = await ImagePicker.getMediaLibraryPermissionsAsync();
console.log(imagePermission.status);
setGalleryPermission(imagePermission.status === 'granted');
if (
imagePermission.status !== 'granted' &&
cameraPermission.status !== 'granted'
) {
alert('Permission for media access needed.');
}
};
useEffect(() => {
permisionFunction();
}, []);
const takePicture = async () => {
if (camera) {
const data = await camera.takePictureAsync(null);
console.log(data.uri);
setImageUri(data.uri);
}
};
const pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
aspect: [1, 1],
quality: 1,
presentationStyle: 0
});
console.log(result);
if (!result.canceled) {
setImageUri(result.assets[0].uri);
}
};
return (
<View style={styles.container}>
<View style={styles.cameraContainer}>
<Camera
ref={(ref) => setCamera(ref)}
style={styles.fixedRatio}
type={type}
ratio={'1:1'}
/>
</View>
<Button title={'Take Picture'} onPress={takePicture} />
<Button title={'Gallery'} onPress={pickImage} />
{imageUri && <Image source={{ uri: imageUri }} style={{ flex: 1 }} />}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
cameraContainer: {
flex: 1,
flexDirection: 'row',
},
fixedRatio: {
flex: 1,
aspectRatio: 1,
},
button: {
flex: 0.1,
padding: 10,
alignSelf: 'flex-end',
alignItems: 'center',
},
});