생각은 길게 코딩은 짧게

[React-Native] React-Native-Vision-Camera 본문

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에 나타나는 사진들을 삭제하면 삭제되는 것까지 완료한 상태이고

추후 디자인 개선과 여러 요소들을 더 추가해볼 생각입니다 !!