본문 바로가기
daily

[react-native] expo-camera 사용하기

by 튜브타고 둥둥 2020. 7. 14.

개인 프로젝트를 시작했습니다 ! 

써보고 싶던 것들을 생각해서 아이디어를 냈고,

웹서비스를 만들까하다 웹서비스보다는 앱에 훨씬 친숙한 요즘에 맞게 앱으로 만들기로 정했어요.

그래서 이미 사용해보았지만 expo와 react-native를 똑같이 사용하는 대신,

지난 프로젝트와는 다르게 ios로 만들 예정이고,

typescript를 이용하고 React-Hooks도 공부하며 사용할 예정입니다.

 

그래서 가장 사용해보고 싶던 카메라와 OCR을 넣었고,

expo-camera에 대해 블로깅을 하고자 합니다.

 

참고 : https://docs.expo.io/versions/latest/sdk/camera/

 

Camera - Expo Documentation

Note: Enabling skipProcessing would cause orientation uncertainty. Image component does not respect EXIF stored orientation information, that means obtained image would be displayed wrongly (rotated by 90°, 180° or 270°). Different devices provide diffe

docs.expo.io

expo 공식 문서에 아주 친절하게 설명이 되어 있어서 그다지 어렵지는 않았던 것 같아요.

 

맨 처음엔 React-Hooks를 사용해봐야겠다 싶어, 

expo 공식 문서에 나온대로 React-Hooks를 이용했고,

React-Hooks는 생각보다 그다지 어렵지 않았고 완성한 후엔 다시 class로 리팩토링 하였습니다.

class component로 리팩토링한 코드로 블로깅을 하려고 합니다.

 

우선 expo-camera를 설치합니다.

expo install expo-camera

 

설치 후, import를 하구요.

import { Camera } from 'expo-camera';

 

가장 첫 번째로 카메라를 이용할 때 카메라 사용 허용 여부를 위한 요청을 합니다.

componentDidMount() {
    (async () => {
        const { status } = await Camera.requestPermissionsAsync();
        this.setHasPermission(status === 'granted');
    })();
}

이 부분은 지난번 프로젝트 때에도 유저의 위치 정보를 가져오는 것에 대한 허용 요청과 비슷해서 쉬웠어요,

setHasPermission 함수는 state에 허용 여부를 반영하는 것인데,

허용(granted)를 하면 true를 아니면 false를 넣어줍니다.

 

그리고 카메라를 렌더합니다.

<Camera
  style={{ width: 300, height: 400 }}
  type={this.state.type}
  ref={(ref) => {
  this.camera = ref;
  }}
 >
    <View
        style={{
        flex: 1,
        backgroundColor: 'transparent',
        flexDirection: 'row',
        }}
    >
        // FLIP : 전면/후면 카메라 변경 버튼, 
        <TouchableOpacity
            style={{
            flex: 0.5,
            alignSelf: 'flex-end',
            alignItems: 'center',
            }}
            onPress={this.setType}
        >
            <Text style={{ fontSize: 18, marginBottom: 10, color: 'white' }} >
              Flip
            </Text>
        </TouchableOpacity>

        // SNAP : 사진 촬영 버튼
        <TouchableOpacity
            style={{
            flex: 0.5,
            alignSelf: 'flex-end',
            alignItems: 'center',
            }}
            onPress={this.setSnap}
        >
            <Text style={{ fontSize: 18, marginBottom: 10, color: 'white' }} >
              SNAP
            </Text>
        </TouchableOpacity>
    </View>
</Camera>

FLIP 버튼과 SNAP 버튼을 추가해서,

전면/후면 카메라로 변경하거나 사진을 찍을 수 있게 합니다.

 

FLIP을 클릭했을 때 카메라를 전면 혹은 후면으로 바꿔주는 함수는 아래와 같아요.

  setType() {
    let currentState = this.state.type;
    let willState =
      currentState === Camera.Constants.Type.back
        ? Camera.Constants.Type.front
        : Camera.Constants.Type.back;
    this.setState({
      type: willState,
    });
  }

상태에 type으로 카메라 전면인지 후면인지를 관리하고,

클릭할때마다 반대로 변경해줍힌다.

콘솔에 찍어보니 front일때는 2, back일때는 1이 찍히더라구요

 

SNAP을 누르면 OCR로 찍힌 사진에서 텍스트를 추출하게 만들었는데,

그 전까지의 과정은 아래와 같습니다.

setSnap = async () => {
    if (this.camera) {
      const options = { quality: 0.5, base64: true };
      let photo = await this.camera.takePictureAsync(options);
      this.setState(
        {
          photo: photo.base64,
          scanning: false,
          uri: photo.uri,
        },
        () => this.callGoogleVIsionApi(this.state.result)
      );
    }
  };

찍은 사진은 base64로 인코딩하고 이걸 callGoogleVIsionApi(OCR을 위한 함수)로 보내주는 방식으로 진행을 했습니다.

this.camera는 Camera의 ref를 나타냅니다.

options의 quality는 0-1.0까지의 숫자가 올 수 있고, 1에 가까울수록 고화질로 압축하는 것이에요.

base64에는 boolean값이 올 수 있고, 나는 이게 필요해서 true로 넣었고,

이 값을 state 내에 photo로 저장하였습니다.

 

scanning은 이 값에 따라 카메라를 보여줄지 안보여줄지를 나타내고,

사진을 찍으면 바로 false로 바꿔 카메라에서 나가도록 만들었습니다.

(참고로 추후 이 부분은 로딩 화면을 새로 만들어 사진을 찍는 순간 로딩화면을 보여주고,

결과가 다 불러와졌을때 로딩화면이 끝나고 결과를 보여주도록 바꿀 예정입니다.)

 

uri를 이용해서 snap 후 카메라에서 나가면 아래처럼 제가 찍은 사진을 보여주게 만들었어요.

<Image
  style={{
  width: 100,
  height: 100,
  resizeMode: 'contain',
  }}
  source={{ uri: this.state.uri }}
/>

카메라를 구동했을 떄의 어플이다.

 

이렇게 expo-camera를 이용하여 원하는 것을 구현해 보았습니다!

자료가 그렇게 많지 않았지만 공식문서에서 대부분의 필요한 내용을 확인할 수 있었어요.

RN camera와 비슷한 부분들이 많아서 RN camera 자료들도 참고해보았습니다.

 

필요한 분들께 도움이 되었으면 좋겠다는 마음을 가지며 expo-camera 블로깅 끝 ! 

 

'daily' 카테고리의 다른 글

[react-native] 갑자기 app crash가 생길때 ...  (0) 2021.01.06
[react-native] IOS 딥링크 연결하기  (1) 2020.12.01
공부를 하면서  (0) 2020.02.20
커리어 바꾸기  (0) 2020.02.17