見出し画像

React Native の expo-camera の使い方

「React Native」の 「expo-camera」の使い方をまとめました。

・Expo SDK 51


前回

1. expo-camera

「expo-camera」は、「Expo」を利用した「React Native」アプリでカメラ機能をサポートするライブラリです。「Expo」は「React Native」アプリの開発を簡単にするツールキットになります。

・カメラの起動と撮影
・カメラ設定の調整
(フラッシュモード、解像度、アスペクト比など)
・パーミッション管理
・カメラのフロント/バック切替

2. expo-camera の使い方

「expo-camera」の使い方は、次のとおりです。

2-1. React Nativeプロジェクトの作成

(1) React Nativeプロジェクトの作成。

npx react-native init my_app
cd my_app

(2) パッケージのインストール。

npx install-expo-modules
npm install expo-camera

2-2. Androidのセットアップ

(1) 「AndroidManifest.xml」に「CAMERA」と「RECORD_AUDIO」のパーミッションを追加。

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
        :
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />

(2) android/build.gradle に以下のブロックを追加。

allprojects {
    repositories {

        // * Your other repositories here *

        // * Add a new maven block after other repositories / blocks *
        maven {
            // expo-camera bundles a custom com.google.android:cameraview
            url "$rootDir/../node_modules/expo-camera/android/maven"
        }
    }
}

2-3. iOSのセットアップ

(1) podのインストール。

cd ios
pod install
cd ..

(2) Xcodeで署名し、iPhoneにインストールできることを確認。
xcworkspaceを開いた時に以下のエラーがでた場合、「Build Settings → Swift Compiler - Language」でバージョン「Swift 4.2」を指定することで解決しました。

(3) 「Info.plist」に以下の項目を追加。

<key>NSCameraUsageDescription</key>
<string>カメラを使用します。</string>
<key>NSMicrophoneUsageDescription</key>
<string>マイクを使用します。</string>

2-4. カメラの起動

(1) コードの編集。

・App.tsx

import { CameraView, useCameraPermissions } from 'expo-camera';
import { useState } from 'react';
import { Button, Text, TouchableOpacity, View } from 'react-native';

// アプリ
const App: React.FC = () => {
  const [permission, requestPermission] = useCameraPermissions();
  const [camera, setCamera] = useState<CameraView | null>(null);

  // カメラパーミッションのロード中
  if (!permission) {
    return <View />;
  }

  // カメラ権限はまだ付与されていない
  if (!permission.granted) {
    return (
      <View style={{ flex: 1, justifyContent: 'center' }}>
        <Button onPress={requestPermission} title="カメラの起動を許可" />
      </View>
    );
  }

  // 写真の撮影
  async function takePicture() {
    if (camera) {
      const photo = await camera.takePictureAsync();
      console.log(photo);
      // ここで撮影した写真を処理(保存、表示など)
    }
  }

  // UI
  return (
    <View style={{ flex: 1, justifyContent: 'center' }}>
    <CameraView 
      style={{ flex: 1 }} 
      ref={(ref) => setCamera(ref)}
    >
    <View style={{ position: 'absolute', bottom: 20, alignSelf: 'center', backgroundColor: 'blue', }}>
        <TouchableOpacity onPress={takePicture}>
          <Text style={{ fontSize: 24, fontWeight: 'bold', color: 'white', padding: 10 }}>写真の撮影</Text>
        </TouchableOpacity>
      </View>
    </CameraView>
  </View>
  );
}

export default App;

(2) コードの実行。

npm start

3. QRコードスキャン

QRコードスキャンして標準出力する機能を追加します。

(1) コードの編集。

import { CameraView, useCameraPermissions, BarcodeScanningResult } from 'expo-camera';
import { useState } from 'react';
import { Button, Text, TouchableOpacity, View } from 'react-native';

// アプリ
const App: React.FC = () => {
  const [permission, requestPermission] = useCameraPermissions();
  const [camera, setCamera] = useState<CameraView | null>(null);

  // カメラパーミッションのロード中
  if (!permission) {
    return <View />;
  }

  // カメラ権限はまだ付与されていない
  if (!permission.granted) {
    return (
      <View style={{ flex: 1, justifyContent: 'center' }}>
        <Button onPress={requestPermission} title="カメラの起動を許可" />
      </View>
    );
  }

  // 写真の撮影
  async function takePicture() {
    if (camera) {
      const photo = await camera.takePictureAsync();
      console.log(photo);
      // ここで撮影した写真を処理(保存、表示など)
    }
  }

  // バーコードスキャン時に呼ばれる
  function onBarcodeScanned(scanningResult: BarcodeScanningResult) {
    // バーコードスキャンした情報
    console.log(scanningResult)
  }

  // UI
  return (
    <View style={{ flex: 1, justifyContent: 'center' }}>
    <CameraView 
      style={{ flex: 1 }} 
      ref={(ref) => setCamera(ref)}
      barcodeScannerSettings={{ barcodeTypes: ["qr"] }}
      onBarcodeScanned={onBarcodeScanned}
    >
    <View style={{ position: 'absolute', bottom: 20, alignSelf: 'center', backgroundColor: 'blue', }}>
        <TouchableOpacity onPress={takePicture}>
          <Text style={{ fontSize: 24, fontWeight: 'bold', color: 'white', padding: 10 }}>写真の撮影</Text>
        </TouchableOpacity>
      </View>
    </CameraView>
  </View>
  );
}

export default App;

(2) コードの実行。
QRコードがカメラ映像に映るとログ出力されます。

npm start
{"boundingBox": {"origin": {"x": 287.2727355957031, "y": 88.36363983154297}, "size": {"height": 101.45454406738281, "width": 150.18182373046875}}, "cornerPoints": [{"x": 88.36363983154297, "y": 287.2727355957031}, {"x": 93.09091186523438, "y": 431.6363525390625}, {"x": 188.36363220214844, "y": 437.4545593261719}, {"x": 189.81817626953125, "y": 294.9090881347656}], "data": "https://docs.expo.dev/", "raw": "https://docs.expo.dev/", "target": 33, "type": "qr"}

【おまけ】 CameraViewのパラメータ

・animateShutter : カメラのシャッターアニメーションを有効にするかどうか (デフォルト:true)
・autofocus : オートフォーカスのモード (デフォルト:off) (iOSのみ)
・barcodeScannerSetting : バーコードスキャナー設定
・enableTorch : タッチを有効にするか (デフォルト:false)
・facing : カメラの向き (front or back、デフォルト:back)
・flash : カメラのフラッシュモード (デフォルト:off)
・mode : カメラモード (picture or video、デフォルト:picture)
・mute : 録画時の音声なし (デフォルト:false)
・pictureSize : 画像サイズ
・ratio : プレビューのアスペクト比 (デフォルト:4:3) (Androidのみ)
・responsiveOrientationWhenOrientationLocked : 画面の向きがロックされている時、カメラの応答性の高い向きを許可するかどうか (iOSのみ)
・videoQuality : ビデオ品質
・videoStabilizationMode : ビデオ録画用に使用するビデオ安定モード (iOSのみ)
・zoom : ズーム (0〜1、デフォルト:0)

・onBarcodeScanned : バーコードが正常にスキャンされた時に呼ばれる
・onCameraReady : カメラプレビュー開始時に呼ばれる
・onMountError : カメラプレビュー開始できなかった時に呼ばれる
・onResponsiveOrientationChanged : レスポンシブな方向が変わった時に呼ばれる (iOS)

次回




この記事が気に入ったらサポートをしてみませんか?