在移动应用程序中,用户经常通过输入他们的信用卡详细信息进行购买。我们可能都有过手动将这 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 <project-name> --template react-native-template-typescript

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

import React from 'react';
import {SafeAreaView, Text} from 'react-native';
​
const App: React.FC = () => {return (<SafeAreaView><Text>Credit Card Scanner</Text></SafeAreaView>);
};
​
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以实现图像拾取功能:

....
<key>NSPhotoLibraryUsageDescription</key>
<string>Allow Access to Photo Library</string>
....

我们还需要在 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 (<SafeAreaView style={styles.container}><StatusBar barStyle={'dark-content'} /><Text style={styles.title}>Credit Card Scanner</Text><Pressable style={styles.galleryBtn} onPress={pickAndRecognize}><Text style={styles.btnText}>Pick from Gallery</Text></Pressable></SafeAreaView>);
};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';
....
<SafeAreaView style={styles.container}>....{device && hasPermissions ? (<View><CameraphotoenableHighQualityPhotosref={camera}style={styles.camera}isActive={true}device={device}/><Pressablestyle={styles.captureBtnContainer}// We will define this method lateronPress={captureAndRecognize}><Image source={Capture} /></Pressable></View>) : (<Text>No Camera Found</Text>)}
</SafeAreaView>

添加相关样式:

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<Camera>(null);const devices = useCameraDevices();let device: any = devices.back;const [hasPermissions, setHasPermissions] = useState<boolean>(false);....
}

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

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

....
<key>NSCameraUsageDescription</key>
<string>Allow Access to Camera</string>
....

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

....<uses-permission android:name="android.permission.CAMERA"/>
....

当我们的应用程序被加载时,我们需要向用户请求权限。让我们编写代码来做到这一点。将以下代码添加到您的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<string>('Scan a Card to see\nCard Number here',);const [isProcessingText, setIsProcessingText] = useState<boolean>(false);const [cardIsFound, setCardIsFound] = useState<boolean>(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 ? (<ActivityIndicatorsize={'large'}style={styles.activityIndicator}color={'blue'}/>) : cardIsFound ? (<Text style={styles.creditCardNo}>{getFormattedCreditCardNumber(processedText)}</Text>) : (<Text style={styles.errorText}>{processedText}</Text>)}
....

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 位信用卡号码。

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

如何使用 React Native 构建信用卡扫描仪相关推荐

  1. 如何使用React Native构建嵌套的抽屉菜单

    by Dhruvdutt Jadhav 由Dhruvdutt Jadhav 如何使用React Native构建嵌套的抽屉菜单 (How to build a nested drawer menu w ...

  2. 如何使用React Native构建新闻应用

    by Mohammed Salman 穆罕默德·萨尔曼(Mohammed Salman) 如何使用React Native构建新闻应用 (How to build a news app with Re ...

  3. 使用React Native构建类似Tinder的加载器

    在这篇文章中我会尝试描述在React Native中构建一个类似Tinder的加载器所遇到的调整我把它分成三个挑战. 挑战1:布局 在上面的截图中,你可以看到头像和它后面的圆,都在屏幕正中间. 感谢 ...

  4. 使用React Native和Spring Boot构建一个移动应用

    "我喜欢编写身份验证和授权代码." 〜从来没有Java开发人员. 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证. Reac ...

  5. 构建了我的第一个React Native应用程序之后,我现在确信这是未来。

    by Taylor Milliman 泰勒·米利曼(Taylor Milliman) 构建了我的第一个React Native应用程序之后,我现在确信这是未来. (After building my ...

  6. 如何构建具有实时搜索功能的React Native FlatList

    by Vikrant Negi 通过Vikrant Negi 如何构建具有实时搜索功能的React Native FlatList (How to build a React Native FlatL ...

  7. 我如何为我的第一个自由客户构建第一个React Native应用程序

    by Charlie Jeppsson 查理·杰普森(Charlie Jeppsson) 我如何为我的第一个自由客户构建第一个React Native应用程序 (How I built my firs ...

  8. React Native Expo开发的OW移动端项目

    iOS演示 开源地址 GitHub Gitee 项目地址 Andorid 版 Android Expo 版(需 Expo 移动端(Android/iOS)) Expo 简介 项目基于Expo的 Rea ...

  9. Shoutem旨在成为React Native移动应用领域的WordPress

    近日,Shoutem推出了新的基于React Native的应用构建器,为开发人员提供了移动应用领域的WordPress. \\ Shoutem让开发人员可以使用一个可视化环境快速创建基于React ...

  10. React Native发布重构路线图

    React Native作为时下最热门的跨平台开发方案,在这两年的移动跨平台方案中可谓一枝独秀,在很多的移动产品中都可以看到它们的影子,相比国内的Weex,RN的迭代更加频繁,性能上也无限的接近原生应 ...

最新文章

  1. 2010.12.14 关于decimal和Numeric类型
  2. nmap脚本(nse)使用总结
  3. TabControl控件和TabPage
  4. Java 调用 C++ (Java 调用 dll)康哥手把手教你
  5. jvm可以运行多种语言吗
  6. HTML动画(难点)
  7. B - Frogger(最短路之多条最短路径中最大权值的最小值)
  8. python必背入门代码-初学Python必背手册
  9. 转------计算机网络面试小宝典
  10. Linux Qt工程组织结构与动态库引用
  11. Bzoj 3339: Rmq Problem Bzoj 3585: mex 莫队,树状数组,二分
  12. 机器学习_周志华_西瓜书_学习笔记_第16章--强化学习
  13. C语言符号常量的使用,C语言常量与符号常量
  14. DIY一个SM2262ENG 2TB Nvme固态硬盘,慧荣SM2262EN主控
  15. 学习日志之synthesis and optimization(4)——banding and sharing
  16. 【用pandas_alive几行代码绘制竞赛动图】全网首发pandas_alive数据可视化中文学习笔记合集,学不会来打我(配置好的venv虚拟环境+拿来即用测试代码+测试数据集+参数api解析)
  17. USB学习笔记(3)HID应用分析
  18. pear php库,PEARX-不依赖 PEAR 的 PEAR 的 PHP 库
  19. 软件测试之计算机基础
  20. 引流脚本软件是干什么的,引流脚本是最靠谱得引流方式?

热门文章

  1. 测试内存条是否兼容软件,内存条不兼容有什么表现
  2. 计算机内存一代,内存条一代二代三代的区别
  3. MacOS 开发 — Dock 显示网速/消息
  4. BLE_BQB Test_Modulation Characteristics, LE Coded (S=8)_RF-PHY/TRM/BV-13-C
  5. WebRTC之视频采集
  6. cookie—基于js的coolie使用
  7. oracle 查看表历史记录,Oracle 查看表操作历史记录并恢复
  8. 【matlab算法原理详解】车牌识别算法
  9. 数据库查询数据去除重复
  10. 手机连接USB通过宽带免费上网