🐷

React NativeでQRコードを読み取る(その1)

2023/04/02に公開

はじめに

今回は、React NativeでQRコードを読み取る方法を紹介します。
QRコードを読み取る方法はいくつかありますが、
そのうちの一つである、react-native-vision-camera
vision-camera-code-scannerを使ってみました。

React Nativeのプロジェクト作成

以下のように、React Nativeのプロジェクトを作成します。

npx react-native@latest init rnqrex01

インストール

現時点ではreact-native-reanimatedのv3系とreact-native-vision-cameraの最新版の相性が悪いようなので、あえてv2系をインストールします。

yarn add react-native-reanimated@^2.14.4 react-native-vision-camera vision-camera-code-scanner
npx pod-install

build.gradleのext配下に以下のように追加します。

android/build.gradle
kotlinVersion = '1.6.20'

パーミッションの設定

iOS

Info.plistの<dict>タグの直下に以下のように追加します。

ios/rnqrex01/Info.plist
<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) はカメラにアクセスする必要があります.</string>

Android

AndroidManifest.xmlにカメラのパーミッションを追加します。

android/app/src/main/AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA" />

以下のようにbabel.config.jsを編集して、react-native-reanimatedのプラグインを追加します。

babel.config.js
module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: [
    [
      'react-native-reanimated/plugin',
      {
        globals: ['__scanCodes'],
      },
    ],
  ],
};

以下のようにApp.tsxを編集します。

App.tsx
import * as React from 'react';
import {useCallback, useEffect, useState} from 'react';

import {StyleSheet, Text} from 'react-native';
import {runOnJS} from 'react-native-reanimated';
import {
  Camera,
  CameraPermissionStatus,
  useCameraDevices,
  useFrameProcessor,
} from 'react-native-vision-camera';
import {BarcodeFormat, scanBarcodes} from 'vision-camera-code-scanner';

export default function App() {
  const [cameraPermission, setCameraPermission] =
    React.useState<CameraPermissionStatus>();

  const devices = useCameraDevices();
  const device = devices.back;
  const [QRCode, setQRCode] = useState<string>();
  useEffect(() => {
    Camera.requestCameraPermission().then(setCameraPermission);
  }, []);

  const onQRCodeScanned = useCallback((code: string) => {
    setQRCode(code);
  }, []);

  const frameProcessor = useFrameProcessor(
    frame => {
      'worklet';
      const qrcodes = scanBarcodes(frame, [BarcodeFormat.QR_CODE], {
        checkInverted: true,
      });
      if (qrcodes.length > 0) {
        runOnJS(onQRCodeScanned)(qrcodes[0].displayValue || '');
      }
    },
    [onQRCodeScanned],
  );

  if (!device) {
    return <Text>背面カメラがありません</Text>;
  }

  if (!cameraPermission) {
    return <Text>カメラの使用を許可してください</Text>;
  }

  return (
    <>
      <Camera
        style={StyleSheet.absoluteFill}
        device={device}
        isActive={true}
        frameProcessor={frameProcessor}
        frameProcessorFps={5}
      />
      <Text style={styles.qrcode}>{QRCode}</Text>
    </>
  );
}

const styles = StyleSheet.create({
  qrcode: {
    fontSize: 40,
    color: 'red',
    fontWeight: 'bold',
  },
});

実行

実行するとこんな感じです。
React Native QRコードスキャナー

以上です。

Discussion