React Native 入門してみた③ Httpアクセス編 - Qiitaにつづいて今回はカメラ実装についての入門です。
カメラ実装
カメラ機能の実装も何かに使うかも?ということで試してみました。
ExpoにCameraのAPIが用意されているので、そちらを使用して実装してみます。
Camera- Expo Documentationに使用サンプルがあるので、サンプルを元に実装します。
実装
ファイル構成
├── App.tsx
├── app.json
├── assets
├── babel.config.js
├── package-lock.json
├── package.json
└── tsconfig.json
こちらも前回同様のTypeScript構成です。
ここではデフォルトのまま特に追加せず、App.tsx
のみ編集します。
とりあえず、上記リンクにあるBasic Example
の実装をコピペ
App.tsx
import React from 'react';
import { Text, View, TouchableOpacity } from 'react-native';
import { Camera, Permissions } from 'expo';
export default class CameraExample extends React.Component {
state = {
hasCameraPermission: null,
type: Camera.Constants.Type.back,
};
async componentDidMount() {
const { status } = await Permissions.askAsync(Permissions.CAMERA);
this.setState({ hasCameraPermission: status === 'granted' });
}
render() {
const { hasCameraPermission } = this.state;
if (hasCameraPermission === null) {
return <View />;
} else if (hasCameraPermission === false) {
return <Text>No access to camera</Text>;
} else {
return (
<View style={{ flex: 1 }}>
<Camera style={{ flex: 1 }} type={this.state.type}>
<View
style={{
flex: 1,
backgroundColor: 'transparent',
flexDirection: 'row',
}}>
<TouchableOpacity
style={{
flex: 0.1,
alignSelf: 'flex-end',
alignItems: 'center',
}}
onPress={() => {
this.setState({
type: this.state.type === Camera.Constants.Type.back
? Camera.Constants.Type.front
: Camera.Constants.Type.back,
});
}}>
<Text
style={{ fontSize: 18, marginBottom: 10, color: 'white' }}>
{' '}Flip{' '}
</Text>
</TouchableOpacity>
</View>
</Camera>
</View>
);
}
}
}
カメラを起動するには実機が必要です。
iOSにExpoアプリをインストールして、iPhoneのカメラでQRコード読み取り起動します。(Expo起動時に表示されるQRコードです。)
起動するとカメラの起動ができます。
上記コードではカメラの起動のみなので、さらに写真を取って保存する処理を実装してみます。
App.tsxを編集します。
...
private camera?: CameraObject;
constructor(props: {}) {
super(props);
}
...
async takePicture() {
if (this.camera) {
const pictureData = await this.camera!.takePictureAsync();
CameraRoll.saveToCameraRoll(pictureData.uri);
}
}
...
まずは、写真を保存する処理を追加します。
CameraObject
のtakePictureAsync
で画像データを取得します。
CameraRoll
のsaveToCameraRoll
に先程取得して画面データのurlを指定して保存します。
つづいてrender
の修正です。
render() {
const { hasCameraPermission } = this.state;
if (hasCameraPermission === null) {
return <View />;
} else if (hasCameraPermission === false) {
return <Text>No access to camera</Text>;
} else {
return (
<View style={{ flex: 1 }}>
<Camera style={{ flex: 1 }} type={this.state.type}
ref={(ref: any) => {
this.camera = ref;
}}
>
<View
style={{
flex: 1,
backgroundColor: 'transparent',
flexDirection: 'row',
}}>
<TouchableOpacity
style={{
flex: 0.1,
alignSelf: 'flex-end',
alignItems: 'center',
}}
onPress={() => {
this.setState({
type: this.state.type === Camera.Constants.Type.back
? Camera.Constants.Type.front
: Camera.Constants.Type.back,
});
}}>
<Text
style={{ fontSize: 18, marginBottom: 10, color: 'white' }}>
{' '}Flip{' '}
</Text>
</TouchableOpacity>
+ <TouchableOpacity
+ style={{
+ flex: 1,
+ alignSelf: 'flex-end',
+ alignItems: 'center',
+ }}
+ onPress={() => this.takePicture()}>
+ <Text
+ style={{ fontSize: 18, marginBottom: 10, color: 'white' }}>
+ {' '}Camera{' '}
+ </Text>
+ </TouchableOpacity>
</View>
</Camera>
</View>
);
}
}
CameraコンポーネントにTouchableOpacityコンポーネントを追加します。
onPress
に先程作成してtakePicutre
関数を指定します。
これで画面下部にCamera
という文字が表示されタップすることで写真を保存出来るようになりました。
とても簡単に実装出来ますね。