React Native
[React-Native] React-Native-Vision-Camera
sayhee
2022. 10. 25. 16:15
728x90
안녕하세요 vision camera를 도전하고 왔습니다 ~!
아직 완벽하게 구현하진 않았지만 원하는 기능들은 추가되고 있어요
자료가 넘 없어서 document를 찾아보면서 했어요 ㅠ
✅ android / app / src / main / AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
✅ Import
import { StyleSheet , Button , View, Image , TouchableOpacity,Text,FlatList} from 'react-native';
import {Camera, useCameraDevices} from 'react-native-vision-camera';
import React, { useRef, useState } from 'react';
import {styles} from '../style/Inpstyle'
✅ Camera view
device : useCameraDevices()를 사용하여 수동으로 가져옵니다
isActive : 카메라가 비디오 프레임을 능동적으로 실행해야하는지 여부를 지정하는 부울 값
const devices = useCameraDevices()
const device = devices.back
if (device == null) return (<></>);
return (
<Camera
ref={camera}
style={StyleSheet.absoluteFill}
device={device}
isActive={true}
photo={true}
/>
)
✅ Taking Photo
const camera = useRef(null)
const [imageURL, setImageURL] = useState([]); //찍은 사진 경로를 저장해 줄 배열
const onPressButton = async () => {
const photo = await camera.current.takeSnapshot({
flash: 'off',
})
setImageURL([...imageURL,"file://"+photo.path]); //파일 add 필수
console.log(photo.path)
}
return(
<View style={styles.buttonStyle}>
<TouchableOpacity style={styles.buttonStyle} onPress={onPressButton}>
<Text>Click me</Text>
</TouchableOpacity>
</View>
)
takeSnapshot인 이유는 takePhoto를 하였을 때 아예 실행이 안 돼서 여러 서치를 통해 바꿔주었어요
아시는 분은 댓글을 달아주세요...ㅠ
처음에 file://을 add 안해주어서 헤맷는데
setImageURL에 file:// 을 add 해주어야 한다는 것을 공식 문서에서 발견하여 추가해주어 해결했어요
✅ List에 찍은 이미지 나열 ( renderItem )
renderItem = ({item, index}) => {
return <TouchableOpacity style={styles.touchableStyle} onPress={()=> console.log(index)}>
<View style={styles.viewStyle} >
<Image source={{uri : item}} style={styles.logo} />
</View>
</TouchableOpacity>
};
const [imageURL, setImageURL] = useState([]); 의 imageURL에 들어있는 요소들을 item값으로 받아옵니다
✅ FlatList
return (
<View style={styles.viewHeaderLayout}>
<FlatList
data={imageURL}
renderItem={renderItem}
horizontal={true}
/>
</View>
)
Flatlist 안에 있는 horizontal = { true } 속성을 사용하여 정렬을 가로로 해주었어요 / default 정렬은 세로 정렬입니다
✅ 전체 코드
import { StyleSheet , Button , View, Image , TouchableOpacity,Text,FlatList} from 'react-native';
import {Camera, useCameraDevices} from 'react-native-vision-camera';
import React, { useRef, useState } from 'react';
import {styles} from '../style/Inpstyle'
function VisionCameraTest() {
const devices = useCameraDevices()
const device = devices.back
const camera = useRef(null)
const [imageURL, setImageURL] = useState([]);
const onPressButton = async () => {
const photo = await camera.current.takeSnapshot({
flash: 'off',
})
setImageURL([...imageURL,"file://"+photo.path]);
console.log(photo.path)
}
renderItem = ({item, index}) => {
return <TouchableOpacity style={styles.touchableStyle} onPress={()=> console.log(index)}>
<View style={styles.viewStyle} >
<Image source={{uri : item}} style={styles.logo} />
</View>
</TouchableOpacity>
};
if (device == null) return (<></>);
return (
<View style={styles.container}>
<View style={styles.viewHeaderLayout}>
<FlatList
data={imageURL}
renderItem={renderItem}
horizontal={true}
/>
</View>
<View style={styles.viewBodyLayout}>
<Camera
ref={camera}
style={StyleSheet.absoluteFill}
device={device}
isActive={true}
photo={true}
/>
</View>
<View style={styles.viewBottomLayout}>
<View style={styles.buttonStyle}>
<Button title='앨범' />
</View>
<View style={styles.buttonStyle}>
<TouchableOpacity style={styles.buttonStyle} onPress={onPressButton}>
<Text>Click me</Text>
</TouchableOpacity>
</View>
<View style={styles.buttonStyle}>
<Button title='등록' />
</View>
</View>
</View>
);
}
export default VisionCameraTest;
css
//VisionCam
container:{
justifyContent:'center',
width:'100%',
backgroundColor:'white',
},
viewHeaderLayout:{
height:'20%',
borderWidth:1,
justifyContent:'center',
padding: 10,
},
viewBodyLayout:{
height:'70%',
borderWidth:1,
},
viewBottomLayout:{
height:'8%',
flexDirection:'row',
borderWidth:1,
justifyContent:'center',
},
buttonStyle:{
width:100,
height:38,
margin:5,
borderWidth:1,
},
touchableStyle:{
flex : 1,
width:160,
height:80,
margin:5,
},
logo:{
width:160,
height:85,
},
현재 flatlist에 나타나는 사진들을 삭제하면 삭제되는 것까지 완료한 상태이고
추후 디자인 개선과 여러 요소들을 더 추가해볼 생각입니다 !!