개인 프로젝트를 시작했습니다 !
써보고 싶던 것들을 생각해서 아이디어를 냈고,
웹서비스를 만들까하다 웹서비스보다는 앱에 훨씬 친숙한 요즘에 맞게 앱으로 만들기로 정했어요.
그래서 이미 사용해보았지만 expo와 react-native를 똑같이 사용하는 대신,
지난 프로젝트와는 다르게 ios로 만들 예정이고,
typescript를 이용하고 React-Hooks도 공부하며 사용할 예정입니다.
그래서 가장 사용해보고 싶던 카메라와 OCR을 넣었고,
expo-camera에 대해 블로깅을 하고자 합니다.
참고 : https://docs.expo.io/versions/latest/sdk/camera/
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 |