• 如何使用 React Native 构建信用卡扫描仪


    在移动应用程序中,用户经常通过输入他们的信用卡详细信息进行购买。我们可能都有过手动将这 16 位数字输入智能手机的令人沮丧的经历。

    许多应用程序正在增加自动化以简化此过程。因此,要输入付款详情,用户可以为他们的信用卡拍照,或者从他们设备的照片库中上传一张照片。很酷,对吧?

    在本文中,我们将学习如何使用Text Recognition API在 React Native 应用程序中实现类似的功能,这是一个基于机器学习套件的 API,可以识别任何基于拉丁语的字符集。我们将使用设备端文本识别 API 并涵盖以下内容:

    • 创建一个新的 React Native 项目

    • 什么是 react-native-cardscan?

    • 集成 react-native-text-recognition

    • 编写卡号识别逻辑

    您可以在此GitHub 存储库中找到本教程的完整代码。我们最终的 UI 将如下图所示:

    创建一个新的 React Native 项目

    首先,我们将创建一个新的 React Native 项目。倾心壁纸3D壁纸App,内含海量无水印高清图片等你下载,无限次数4K画质!如果您想将信用卡扫描功能添加到您现有的项目中,请随意跳过此部分。

    在您的首选文件夹目录中,在终端中运行以下命令以创建一个新的 React Native 项目:

    npx react-native init  --template react-native-template-typescript

    在您首选的 IDE 中打开项目并将App.tsx文件中的代码替换为以下代码:

    import React from 'react';
    import {SafeAreaView, Text} from 'react-native';
    ​
    const App: React.FC = () => {
      return (
        
          Credit Card Scanner
        
      );
    };
    ​
    export default App;

    现在,让我们运行应用程序。对于 iOS,我们需要在构建项目之前安装 pod:

    cd ios && pod install && cd ..

    然后,我们可以构建 iOS 项目:

    yarn ios

    对于Android,我们可以直接构建项目:

    yarn android

    上述步骤将启动Metro 服务器以及 iOS 和 Android 模拟器,然后在它们上运行应用程序。懒懒视频看片App,蓝光4K无限制顺畅秒播,内置10多条线路速度达16M/s!目前,使用上面的代码App.tsx,我们只会看到一个带有文本阅读的空白屏幕Credit Card Scanner。

    什么是 react-native-cardscan?

    react-native-cardscan是CardScan的一个包装库,它是一个用于扫描借记卡和信用卡的简约库。react-native-cardscan 为 React Native 应用程序中的信用卡扫描提供了简单的即插即用使用。但是,在撰写本文时,react-native-cardscan 已不再维护并且已弃用。Stripe 正在将 react-native-cardscan 集成到自己的移动应用支付解决方案中。您可以在 GitHub 上查看新的存储库,但是在撰写本文时它仍在开发中。

    由于此库已弃用,我们将使用react-native-text-recognition创建自己的自定义信用卡扫描逻辑。

    集成 react-native-text-recognition

    react-native-text-recognition是围绕 iOS 上的 Vision 框架和 Android 上的 Firebase ML 构建的包装库。精英证件照VIP解锁版App,支持一键换背景、证件照大小等,免费无限制使用!如果您在生产应用程序中实现卡片扫描,我建议您创建自己的本机模块用于文本识别。但是,为了本教程的简单性,我将使用这个库。

    让我们编写代码来扫描信用卡。在我们集成文本识别之前,让我们添加我们需要的其他帮助库react-native-vision-camera和react-native-image-crop-picker。我们将使用这些库分别从我们设备的相机中捕捉照片并从手机图库中挑选图像:

    yarn add react-native-image-crop-picker react-native-vision-camera
    // Install pods for iOS
    cd ios && pod install && cd ..

    如果您使用的是 React Native ≥v0.69,则由于在较新的架构中所做的更改,react-native-vision-camera 将无法构建。请遵循此PR中的更改以获取解决方案。

    现在我们的辅助依赖项已经安装,让我们安装 react-native-text-recognition:

    yarn add react-native-text-recognition
    pod install

    设置好依赖项后,让我们开始编写代码。添加以下代码App.tsx以实现图像拾取功能:

    ....
    NSPhotoLibraryUsageDescription
    Allow Access to Photo Library
    ....

    我们还需要在 iOS 上访问用户照片库的权限。为此,请将以下代码添加到您的 iOS 项目info.plist文件中:

    import React from 'react';
    import {SafeAreaView, Text, StatusBar, Pressable} from 'react-native';
    import ImagePicker, {ImageOrVideo} from 'react-native-image-crop-picker';
    
    const App: React.FC = () => {
    
      const pickAndRecognize: () => void = useCallback(async () => {
        ImagePicker.openPicker({
          cropping: false,
        })
          .then(async (res: ImageOrVideo) => {
            console.log('res:', res);
          })
          .catch(err => {
            console.log('err:', err);
          });
      }, []);
    
      return (
        
          
          Credit Card Scanner
          
            Pick from Gallery
          
        
      );
    };
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        alignItems: 'center',
        backgroundColor: '#fff',
      },
      title: {
        fontSize: 20,
        fontWeight: '700',
        color: '#111',
        letterSpacing: 0.6,
        marginTop: 18,
      },
      galleryBtn: {
        paddingVertical: 14,
        paddingHorizontal: 24,
        backgroundColor: '#000',
        borderRadius: 40,
        marginTop: 18,
      },
      btnText: {
        fontSize: 16,
        color: '#fff',
        fontWeight: '400',
        letterSpacing: 0.4,
      },
    });
    
    export default App;

    在上面的代码中,我们在视图中添加了一些文本和样式,但主要部分是我们声明pickAndRecognize函数的地方。请记住,我们并没有在这个函数中做任何与识别相关的事情;我们命名它是因为我们稍后会Text Recognition在这个函数中添加逻辑。

    目前,上述代码的输出将如下所示:

    现在,我们可以从用户的照片库中挑选图像。让我们还添加用于从相机捕获图像并在 UI 上查看相机预览的功能。

    将以下代码添加到您的App.tsx return 语句中:

    // Export the asset from a file like this or directly use it.
    import {Capture} from './assets/icons'; 
    ....
    
          ....
          {device && hasPermissions ? (
            
              
              
                
              
            
          ) : (
            No Camera Found
          )}
    

    添加相关样式:

    const styles = StyleSheet.create({
    ....
      camera: {
        marginVertical: 24,
        height: 240,
        width: 360,
        borderRadius: 20,
        borderWidth: 2,
        borderColor: '#000',
      },
      captureBtnContainer: {
        position: 'absolute',
        bottom: 28,
        right: 10,
      },
    ....
    });

    我们还需要创建一些状态变量和引用:

    const App: React.FC = () => {
      const camera = useRef(null);
      const devices = useCameraDevices();
      let device: any = devices.back;
      const [hasPermissions, setHasPermissions] = useState(false);
      ....
    }

    我们正在显示Image 相机视图以选择图片。您可以继续下载资产。

    在我们预览相机之前,我们需要添加访问我们设备相机的权限。为此,请将以下字符串添加到您的 iOS 项目info.plist文件中:

    ....
    NSCameraUsageDescription
    Allow Access to Camera
    ....

    对于 Android,请将以下代码添加到您的AndroidManifest.xml文件中:

    ....
        
    ....

    当我们的应用程序被加载时,我们需要向用户请求权限。让我们编写代码来做到这一点。将以下代码添加到您的App.tsx文件中:

    ....
      useEffect(() => {
        (async () => {
          const cameraPermission: CameraPermissionRequestResult =
            await Camera.requestCameraPermission();
          const microPhonePermission: CameraPermissionRequestResult =
            await Camera.requestMicrophonePermission();
          if (cameraPermission === 'denied' || microPhonePermission === 'denied') {
            Alert.alert(
              'Allow Permissions',
              'Please allow camera and microphone permission to access camera features',
              [
                {
                  text: 'Go to Settings',
                  onPress: () => Linking.openSettings(),
                },
                {
                  text: 'Cancel',
                },
              ],
            );
            setHasPermissions(false);
          } else {
            setHasPermissions(true);
          }
        })();
      }, []);
    ....

    现在,我们的应用 UI 中有一个工作的相机视图:

    现在我们的相机视图正在工作,让我们添加代码以从相机中捕获图像。

    还记得captureAndRecognize我们想从捕获按钮触发的方法吗?现在让我们定义它。在下面添加方法声明App.tsx:

    ....
      const captureAndRecognize = useCallback(async () => {
        try {
          const image = await camera.current?.takePhoto({
            qualityPrioritization: 'quality',
            enableAutoStabilization: true,
            flash: 'on',
            skipMetadata: true,
          });
          console.log('image:', image);
        } catch (err) {
          console.log('err:', err);
        }
      }, []);
    ....

    与该pickAndRecognize方法类似,我们还没有在该方法中添加信用卡识别逻辑。我们将在下一步中这样做。

    编写卡号识别逻辑

    我们现在能够从我们设备的照片库和相机中获取图像。现在,我们需要编写逻辑,它将执行以下操作:

    • 将图像作为输入并返回该图像中识别的所有文本的字符串数组

    • 遍历数组中返回的字符串并检查每个项目是否是潜在的信用卡号

    • 如果我们找到信用卡号,我们将返回该字符串并显示

    • 如果我们没有找到任何匹配的字符串,那么我们会显示一个错误No Valid Credit Card Found

    这些步骤非常简单。我们来写方法:

    const findCardNumberInArray: (arr: string[]) => string = arr => {
      let creditCardNumber = '';
      arr.forEach(e => {
        let numericValues = e.replace(/\D/g, '');
        const creditCardRegex =
          /^(?:4\[0-9]{12}(?:[0-9]{3})?|[25\][1-7]\[0-9]{14}|6(?:011|5[0-9\][0-9])\[0-9]{12}|3[47\][0-9]{13}|3(?:0\[0-5]|[68\][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/;
        if (creditCardRegex.test(numericValues)) {
          creditCardNumber = numericValues;
          return;
        }
      });
      return creditCardNumber;
    };
    
    const validateCard: (result: string[]) => void = result => {
        const cardNumber = findCardNumberInArray(result);
        if (cardNumber?.length) {
          setProcessedText(cardNumber);
          setCardIsFound(true);
        } else {
          setProcessedText('No valid Credit Card found, please try again!!');
          setCardIsFound(false);
        }
    };

    在上面的代码中,我们编写了两个方法,validateCard并且findCardNumberInArray. 该validateCard方法采用一个string[]或一组字符串的一个参数。然后,它将该数组传递给该findCardNumberInArray方法。如果在数组中找到信用卡号字符串,则此方法将其返回。如果不是,则返回一个空字符串。


    超过 20 万开发人员使用 LogRocket 来创造更好的数字体验了解更多 →


    然后,我们检查cardNumber变量中是否有字符串。如果是,我们设置一些状态变量,否则,我们设置状态变量显示错误。

    让我们看看该findCardNumberInArray方法是如何工作的。此方法还采用 a 的一个参数string[]。然后,它遍历each数组中的元素并从字符串中删除所有非数字值。最后,它用 a 检查字符串regex,检查字符串是否是有效的信用卡号。

    如果字符串与 匹配regex,则我们将该字符串作为信用卡号从该方法返回。如果没有字符串匹配regex,那么我们返回一个空字符串。

    您还会注意到我们尚未在代码中声明这些新的状态变量。现在让我们这样做。将以下代码添加到您的App.tsx文件中:

    ....
      const [processedText, setProcessedText] = React.useState(
        'Scan a Card to see\nCard Number here',
      );
      const [isProcessingText, setIsProcessingText] = useState(false);
      const [cardIsFound, setCardIsFound] = useState(false);
    ....

    现在,我们只需要将validateCard方法插入我们的代码中。使用下面的相应代码编辑您的pickAndRecognize和方法:captureAndRecognize

    ....
      const pickAndRecognize: () => void = useCallback(async () => {
        ....
          .then(async (res: ImageOrVideo) => {
            setIsProcessingText(true);
            const result: string[] = await TextRecognition.recognize(res?.path);
            setIsProcessingText(false);
            validateCard(result);
          })
          .catch(err => {
            console.log('err:', err);
            setIsProcessingText(false);
          });
      }, []);
    
      const captureAndRecognize = useCallback(async () => {
        ....
          setIsProcessingText(true);
          const result: string[] = await TextRecognition.recognize(
            image?.path as string,
          );
          setIsProcessingText(false);
          validateCard(result);
        } catch (err) {
          console.log('err:', err);
          setIsProcessingText(false);
        }
      }, []);
    ....

    这样,我们就完成了!我们只需要在我们的 UI 中显示输出。为此,请将以下代码添加到您的App.tsx return 语句中:

    ....
          {isProcessingText ? (
            
          ) : cardIsFound ? (
            
              {getFormattedCreditCardNumber(processedText)}
            
          ) : (
            {processedText}
          )}
    ....

    ActivityIndicator如果正在进行一些文本处理,上面的代码会显示一个或加载器。如果我们找到了一张信用卡,它会将其显示为文本。您还会注意到我们正在使用一种getFormattedCreditCardNumber方法来呈现文本。我们接下来会写。如果所有条件都是false,则意味着我们有错误,因此我们显示带有错误样式的文本。

    现在让我们声明getFormattedCreditCardNumber方法。将以下代码添加到您的App.tsx文件中:

    ....
    ​
    const getFormattedCreditCardNumber: (cardNo: string) => string = cardNo => {
      let formattedCardNo = '';
      for (let i = 0; i < cardNo?.length; i++) {
        if (i % 4 === 0 && i !== 0) {
          formattedCardNo += ` • ${cardNo?.[i]}`;
          continue;
        }
        formattedCardNo += cardNo?.[i];
      }
      return formattedCardNo;
    };
    ....

    上面的方法有一个参数,cardNo,它是 a string。然后,它遍历并在每四个字母之后cardNo插入一个字符。•这只是一个格式化信用卡号字符串的实用函数。

    我们的最终输出 UI 将如下所示:

    结论

    在本文中,我们学习了如何通过添加信用卡扫描功能来改进我们的移动应用程序。使用react-native-text-recognition库,我们将应用程序设置为从设备的相机中捕获照片并从手机图库中挑选图像,从而识别 16 位信用卡号码。

    文本识别不仅限于信用卡扫描。您可以使用它来解决许多其他业务问题,例如为收据、名片等特定任务自动输入数据!感谢您的阅读。希望您喜欢这篇文章,如果您有任何问题,请务必发表评论。

  • 相关阅读:
    Bean拷贝工具类推荐
    [CISCN2019 总决赛 Day2 Web1]Easyweb
    springboot+微信小程序健康饮食系统毕业设计源码280920
    vscode自动添加备注及函数信息
    前端面试问题(3)
    如何处理ChatGPT在文本生成中的语法错误和不合理性?
    RabbitMQ部署指南
    Mysql 事务的概念-隔离级别-锁
    【洛谷】P5662 纪念品
    sonarqube-9.6 & postgresql-13安装
  • 原文地址:https://blog.csdn.net/weixin_47967031/article/details/127422492