OpenHarmony应用实现二维码扫码识别 原创 精华
OpenHarmony应用实现二维码扫码识别
概念介绍
二维码的应用场景非常广泛,在购物应用中,消费者可以直接扫描商品二维码,浏览并购买产品,如图是购物应用的扫描二维码的页面。
本文就以橘子购物示例应用为例,来讲解OpenHarmony应用二维码开发相关的技术点。
我们先看下二维码相关的几个概念。
- 二维码生成
OpenHarmony应用框架提供了QRCode组件,用于显示单个二维码的组件。该组件只能用于显示二维码,无法显示条码与解析码内容。
- 二维码解析
OpenHarmony提供了功能强大的三方库 @ohos/zxing,是一个解析/生成一维码/二维码的库。详细内容可以参考@ohos/zxing。
二维码解析时,通常有两种方式,使用相机拍摄获取图片或打开相册选取图片,然后图片解析合适的图片格式,进行二维码解析。
橘子购物示例应用扫描二维码的示例图:
配置文件
了解了二维码相关的概念后,我们看下橘子购物示例应用的oh-package.json5配置文件。
在橘子购物示例应用中,实现首页二维码扫描的页面的文件位置为:entry/src/main/ets/pages/ScanPage.ets。文件内容如下:
内容非常简单,主要是导入的自定义组件QRCodeScanComponent,这个组件的代码来自:二维码扫描示例应用,后文我们这样分析如何开发这个二维码扫描应用。
从这一行,可以了解到OpenHarmony应用如何引用ohpm本地三方库。
oh-package.json5配置文件片段如下:
开发步骤
我们来看二维码扫描功能是如何开发的。
导入ohpm三方库
在开发前,我们需要导入ohpm组件库:@ohos/zxing。可以使用命令行方式导入ohpm install @ohos/zxing
,也可以直接在文件entry\oh-package.json5中配置,如文件片段所示。
可以看出,二维码扫描的核心代码存放在Feature目录,是一个独立的module模块,方便复用:
“@ohos/feature-qr-code-scan”: “file:…/Feature”。
相机服务
CameraService.ets文件相机服务构造函数中,会创建一个图片接收器。
该图片接收器可以监听’imageArrival’事件,当相机拍照时会触发该事件。在监听事件的回调函数里,实现对拍照的图片进行处理。
CameraService.ets文件相机服务构造函数:
在CameraService.ets文件创建相机函数中,主要包含如下几个步骤:
- 获取支持的相机
根据context获取CameraManager,然后获取支持的相机(摄像头)。如果没有支持的相机,则然后。
如有支持的相机,则默认使用相机列表中的第一个。实际应用中,对于二维码扫描,需要使用后置相机摄像头。
- 获取相机输入输出流
首先,根据指定的相机,创建相机输入流this.cameraInput
。
然后,获取相机的cameraOutputCapability参数,接着创建两个输出流:
1、 预览输出流
创建相机预览输出流this.previewOutput,使用的surfaceId来自XComponent组件。预览输出流,对应相机拍照前的图片预览。
2、相片输出流
创建相片输出流this.photoOutput,使用的receivingSurfaceId来自上文创建的图片接收器。相片输出流,用于保存到相片。
- 配置相机会话
配置相机会话,也比较简单,添加输入流和输出流即可,见代码及其注释。
CameraService.ets文件创建相机函数:
CameraService.ets文件拍照函数中,指定相片参数设置,然后调用capture()函数完成拍照。
拍照后会触发图片接收器的’imageArrival’事件。拍照函数在使用相机扫描二维码的时候调用。
该图片接收器可以监听’imageArrival’事件,当相机拍照时会触发该事件。在监听事件的回调函数里,实现对拍照的图片进行处理。
CameraService.ets文件拍照函数:
二维码解析实现代码
二维码解析类文件为:QRCodeParser.ets,支持拍照识别二维码,还支持从相册选择二维码图片进行识别。
我们首先看下如何解析从相机获取的二维码图片,对应函数为:parseQRCodeImageFromCamera
,该类指定一个时间随机的图片文件名,图片归档格式,然后继续调用函数parseQRCodeImageWithNameFromCamera
。
在函数parseQRCodeImageWithNameFromCamera
中,注册图片接收器监听’imageArrival’事件,在监听函数里,对二维码图片进行解析识别。
当相机对二维码拍照后,二维码图片会被保存到指定的目录下,返回文件URI。保存图片的函数createPublicDirFileAsset
的实现,可以自行查阅源码。
根据返回的图片URI,调用函数parseImageQRCode
对二维码进行解析。函数parseImageQRCode
后文会介绍。
如果解析失败,弹窗提示解析失败。如果解析成功,会被解析结果保存到AppStorage。
保存到AppStorage的二维码解析结果会被@watch装饰器的变量监视,当监视到有二维码识别结果后,会在界面展示,后文会介绍。
QRCodeParser.ets文件parseQRCodeImageWithNameFromCamera函数代码:
二维码解析类文件为:QRCodeParser.ets,支持拍照识别二维码,还支持从相册选择二维码图片进行识别。
我们接着,再看下如何解析从相册里挑选的二维码图片。
参数imageSrc为选定图片的URI地址。
getImageSource()代码可以自行查询,实现根据图片URI返回图片的宽、高,以及图片的pixelMap数据。然后,把像素数据写入ArrayBuffer,供zxing二维码识别程序使用。
函数RGBLuminanceSource、BinaryBitmap、BinaryBitmap等都是zxing的类。通过调用MultiFormatReader的decode函数对二维码图像进行解析。
如果解析成功,会返回成功的标记和解析的结果。
如果解析失败,会在catch语句块里进行处理,会返回失败的标记和解析失败的原因。
QRCodeParser.ets文件parseImageQRCode函数代码:
相机扫描识别二维码
在文件QRCodeScanComponent.ets中实现了二维码扫描自定义组件。我们看下该文件中如何实现相机扫描二维码的。
在二维码扫描组件的aboutToAppear()函数调用的watchCameraPermission()函数,用于使用相机扫描二维码进行识别。
在watchCameraPermission()函数中,使用setInterval函数每100ms判断下是否具有相机权限,当有相机权限的时候,才能使用相机扫描二维码。
当具备相机权限时 ,使用setInterval函数每4000ms轮询判断下是否识别到二维码图片,如果识别到则取消执行轮询。
如果没有识别到二维码,则继续调用函数takePicture()拍照。调用该函数后,会触发图片接收器的监听事件’imageArrival’,对这个事件的监听分析,见上文。
文件QRCodeScanComponent.ets中,相机拍照识别二维码的代码片段:
识别相册二维码图片
在文件QRCodeScanComponent.ets中实现了二维码扫描自定义组件。我们看下该文件中如何识别相册二维码图片。
首先,设置this.isQRCodeScanStopped为true,这个会关闭相机拍照识别二维码。
然后,通过startAbilityForResult启动相册应用,供用户选择二维码图片。
如果选择图片失败,则弹窗报错。
如果选择图片成功,则调用二维码解码函数parseImageQRCode完成对图片二维码的识别。
如果识别二维码成功,则弹窗展示二维码结果。
如果识别识别,则toast展示:未识别到二维码。
文件QRCodeScanComponent.ets中,相册选择二维码图片进行识别代码片段:
二维码扫描组件界面
在文件QRCodeScanComponent.ets中实现了二维码扫描自定义组件。我们看下二维码扫描组件的页面布局。
整个页面使用Stack进行堆叠布局。
如果有相机权限,会XComponent组件,用于展示相机的预览输出流。XComponent组件的onLoad函数里会创建相机,onDestroy函数里会释放相机。
Image($r('app.media.scan_border'))
图片就是二维码扫描框,引导用户把二维码放到框内进行扫描识别。
Divider是个分割线,该分割线使能了动画效果,在识别二维码的过程中,分割线从二维码识别框里从上到下移动。扫描动画实现代码如下:
Text($r('app.string.putTheQRCodeToScan'))
引导用户把二维码放到框内进行扫描识别。
Image($r('app.media.scan_back'))
返回退出应用。
Image($r('app.media.scan_photo'))
从相册里挑选二维码图片进行识别。
运行测试效果
可以下载橘子购物示例应用代码,使用DevEco Studio编译构建,使用Simulator模拟器或者真实设备进行运行体验。可以体验下使用相机对二维码图片进行识别,还可以尝试下识别相册中的二维码图片。
注意事项
当前二维码示例应用识别相册的二维码,弹出识别结果后,程序会崩溃,已经提单跟踪。示例程序待改进。
使用相机功能直接拍摄二维码的功能,一直没有成功运行,需要进一步优化。
一直都想学习下相机这块,借这个机会了解下
扫码在中国普及的比较广泛,外国比较差,正好适合鸿蒙系统
OpenHarmony4.1开发者手机环境下最多能识别多少字符