You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native安装视觉相机等库后报错及二维码扫描器实现求助

解决Frame Processor错误 + 实现二维码扫描功能

一、修复「Frame Processor threw an error: Value is undefined, expected an Object」错误

这个问题大多是依赖配置不完整或Frame Processor函数写法不符合要求导致的,按以下步骤排查:

1. 确认Reanimated Babel配置正确

在项目根目录的babel.config.js中,必须将Reanimated插件放在所有插件的最后:

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: [
    // 其他插件(如react-native-screens等)放在前面
    'react-native-reanimated/plugin',
  ],
};

配置完成后清除缓存重启服务:

npx react-native start --reset-cache

2. 启用Vision Camera的Frame Processor支持

  • iOS:在ios/Podfile最顶部添加以下代码,然后重新安装Pods:
    $RNVCameraEnableFrameProcessor = true
    
    执行命令:
    cd ios && pod install && cd ..
    
  • Android:在android/app/build.gradle的defaultConfig块中添加配置:
    defaultConfig {
      // 原有配置...
      resValue "bool", "RNVCameraEnableFrameProcessor", "true"
    }
    

3. 规范Frame Processor函数写法

所有用于帧处理的函数必须添加'worklet'标记,确保函数在UI线程外执行:

const scanProcessor = (frame) => {
  'worklet';
  // 帧处理逻辑
};

二、实现二维码扫描(替代弃用的QRScanner)

推荐使用react-native-vision-camera + @visioncamera/barcode-scanner组合,这是目前React Native生态中最稳定的条码扫描方案。

1. 安装依赖

npm install react-native-vision-camera @visioncamera/barcode-scanner react-native-reanimated
# 或使用yarn
yarn add react-native-vision-camera @visioncamera/barcode-scanner react-native-reanimated

2. 配置相机权限

  • iOS:在ios/[项目名]/Info.plist中添加相机权限描述:
    <key>NSCameraUsageDescription</key>
    <string>需要访问相机进行二维码扫描</string>
    
  • Android:在android/app/src/main/AndroidManifest.xml中添加权限:
    <uses-permission android:name="android.permission.CAMERA" />
    

3. 核心代码实现

import React, { useState, useEffect } from 'react';
import { View, Text, StyleSheet, Platform, PermissionsAndroid } from 'react-native';
import { Camera, useCameraDevices, useFrameProcessor } from 'react-native-vision-camera';
import { BarcodeScanner, BarcodeFormat } from '@visioncamera/barcode-scanner';
import { runOnJS } from 'react-native-reanimated';

const QrScannerScreen = () => {
  const [hasCameraPermission, setHasCameraPermission] = useState(false);
  const [scannedResult, setScannedResult] = useState(null);
  const devices = useCameraDevices();
  const backCamera = devices.back;

  // 请求相机权限
  useEffect(() => {
    const requestPermission = async () => {
      const iosPerm = await Camera.requestCameraPermission();
      let androidPerm = true;
      
      if (Platform.OS === 'android') {
        androidPerm = await PermissionsAndroid.request(
          PermissionsAndroid.PERMISSIONS.CAMERA
        ) === PermissionsAndroid.RESULTS.GRANTED;
      }

      setHasCameraPermission(iosPerm === 'authorized' && androidPerm);
    };
    requestPermission();
  }, []);

  // 帧处理器:实时扫描二维码
  const frameProcessor = useFrameProcessor((frame) => {
    'worklet';
    // 只扫描QR_CODE格式
    const barcodes = BarcodeScanner.scan(frame, [BarcodeFormat.QR_CODE]);
    if (barcodes.length > 0) {
      // 将扫描结果同步到JS线程
      runOnJS(setScannedResult)(barcodes[0].displayValue);
      // 可选:扫描到结果后暂停相机
      // runOnJS(() => cameraRef.current?.pausePreview())();
    }
  }, []);

  if (!backCamera) return <Text>加载相机设备中...</Text>;
  if (!hasCameraPermission) return <Text>请授予相机权限</Text>;

  return (
    <View style={styles.container}>
      {/* 相机预览 */}
      <Camera
        style={StyleSheet.absoluteFill}
        device={backCamera}
        isActive={true}
        frameProcessor={frameProcessor}
        frameProcessorFps={8} // 平衡扫描灵敏度与性能,可调整
      />
      {/* 自定义扫描框遮罩(替代react-native-hole,避免依赖冲突) */}
      <View style={styles.maskLayer}>
        <View style={styles.scanFrame} />
      </View>
      {/* 扫描结果展示 */}
      {scannedResult && (
        <View style={styles.resultBox}>
          <Text style={styles.resultText}>扫描结果:{scannedResult}</Text>
        </View>
      )}
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#000',
  },
  maskLayer: {
    flex: 1,
    backgroundColor: 'rgba(0,0,0,0.7)',
    justifyContent: 'center',
    alignItems: 'center',
  },
  scanFrame: {
    width: 260,
    height: 260,
    borderWidth: 2,
    borderColor: '#fff',
    borderRadius: 12,
  },
  resultBox: {
    position: 'absolute',
    bottom: 60,
    left: 24,
    right: 24,
    backgroundColor: 'rgba(255,255,255,0.95)',
    padding: 16,
    borderRadius: 8,
  },
  resultText: {
    fontSize: 16,
    color: '#333',
    textAlign: 'center',
  },
});

export default QrScannerScreen;

4. 常见问题排查

  • 若仍出现Frame Processor错误:
    1. 确认所有依赖版本兼容(建议使用react-native-vision-camera和@visioncamera/barcode-scanner的最新稳定版)
    2. 彻底清理缓存:删除node_modules、ios/Pods、android/build目录,重新安装依赖
    3. 暂时移除react-native-hole,先确保扫描功能正常,再尝试集成遮罩(可用上述代码中的自定义遮罩替代)
  • 扫描灵敏度低:可提高frameProcessorFps值(最大不超过15),或确保二维码处于扫描框中央

内容的提问来源于stack exchange,提问作者React_Coder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 14:15:42