鸿蒙|能力特性-扫码开放能力

4 阅读4分钟

概览:本文从默认界面扫码入手,讲解如何通过startScanForResult快速调起系统扫码界面(无需申请相机权限),并获取扫码结果;随后演示如何识别相册中的条形码、二维码等图像;最后介绍通过createBarcode将文本生成自定义码图的能力。Scan Kit基于AI算法,支持暗光、模糊、曲面等多种复杂场景,显著提升识别成功率。

扫码能力介绍

Scan Kit(统一扫码服务)作为软硬协同的系统级扫码服务。只需少量的接入工作,无需在应用中开发专门的扫码模块,即可通过系统级扫码入口实现扫码到应用的跳转。同时还为开发者提供了面向各种场景的码图识别和生成能力。

Scan Kit应用了多项计算机视觉技术和AI算法技术,不仅实现了远距离自动扫码,同时还针对多种复杂扫码场景(如暗光、污损、模糊、小角度、曲面码等)做了识别优化,提升扫码成功率与用户体验。

默认界面扫码

默认界面扫码能力提供系统级体验一致的扫码界面,包含相机预览流,相册扫码入口,暗光环境闪光灯开启提示。Scan Kit默认界面扫码对系统相机权限进行了预授权且调用期间处于安全访问状态,无需开发者再次申请相机权限。适用于不同扫码场景的应用开发。

默认界面扫码能力提供了系统级体验一致的扫码界面以及相册扫码入口,支持单码和多码识别,支持多种识码类型,请参见ScanType。无需使用三方库就可帮助开发者的应用快速处理各种扫码场景。

默认扫码业务流程:

1、用户向开发者的应用发起扫码请求。
2、开发者的应用通过调用Scan Kit的startScanForResult 接口启动扫码界面。
3、系统首次使用默认界面扫码功能时,会向用户弹出隐私横幅提醒。
4、用户可以点击关闭隐私横幅,重新打开应用的扫码界面将不再显示隐私横幅提醒,显示安全访问提示,3s后消失。
5Scan Kit通过Callback回调函数或Promise方式返回扫码结果。
6、用户进行多码扫描时,需点击选择其中一个码图获取扫码结果返回。单码扫描则可直接返回扫码结果。
7、解析码值结果跳转应用服务页。

调用startScanForResult方法拉起默认界面扫码,然后通过Promise方式得到扫码结果。scanCore提供扫码类型定义,scanBarcode提供拉起默认界面扫码的方法和参数。

import { scanCore, scanBarcode } from '@kit.ScanKit';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct BasicScan {
  build() {
    Column() {
      Row() {
        Button('默认界面扫码')
          .backgroundColor('#0D9FFB')
          .fontSize(20)
          .fontColor($r('sys.color.comp_background_list_card'))
          .fontWeight(FontWeight.Normal)
          .align(Alignment.Center)
          .type(ButtonType.Capsule)
          .width('90%')
          .height(40)
          .margin({ top: 5, bottom: 5 })
          .onClick(() => {
            let options: scanBarcode.ScanOptions = {
              scanTypes: [scanCore.ScanType.ALL], // 识别所有类型码
              enableMultiMode: true, // 支持多码同时识别
              enableAlbum: true // 允许从相册选图扫码
            };
            try {
              scanBarcode.startScanForResult(this.getUIContext().getHostContext(), options,
                (error: BusinessError, result: scanBarcode.ScanResult) => {
                  if (error) {
                    console.log("扫码信息获取失败");
                    return;
                  }
                  // 解析码值结果跳转应用服务页
                  console.log("扫码结果", JSON.stringify(result));
                })
            } catch (error) {
              console.log("扫码能力调用失败");
            }
          })
      }
      .height('100%')
    }
    .width('100%')
  }
}

扫码识别相册图像

图片识码能力支持对图库中的条形码、二维码、MULTIFUNCTIONAL CODE进行识别,并获得码类型、码值、码位置信息。该能力可用于一图单码和一图多码的识别,比如条形码、付款码等。

通过picker拉起图库的图片,并根据选择的图片定义识码参数inputImage。调用detectBarcode.decode接口解析码图。通过Promise回调函数得到扫码结果,InputImage对象中uri参数推荐通过picker方式获取。

import { scanCore, scanBarcode, detectBarcode } from '@kit.ScanKit';
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct DetectPage {
  build() {
    Column() {
      Button("扫描相册图片")
        .backgroundColor('#0D9FFB')
        .fontSize(20)
        .fontColor($r('sys.color.comp_background_list_card'))
        .fontWeight(FontWeight.Normal)
        .align(Alignment.Center)
        .type(ButtonType.Capsule)
        .width('90%')
        .height(40)
        .margin({ top: 5, bottom: 5 })
        .onClick(() => {
          let options: scanBarcode.ScanOptions = {
            scanTypes: [scanCore.ScanType.ALL], // 识别所有类型码
            enableMultiMode: true, // 支持多码同时识别
          }
          // 通过picker拉起图库的图片
          let photoOption = new photoAccessHelper.PhotoSelectOptions();
          photoOption.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
          photoOption.maxSelectNumber = 1;
          let photoPicker = new photoAccessHelper.PhotoViewPicker();
          photoPicker.select(photoOption).then((result) => {
            // 定义识码参数inputImage,其中uri为picker选择图片
            let inputImage: detectBarcode.InputImage = { uri: result.photoUris[0] };
            try {
              // 调用图片识码接口
              detectBarcode.decode(inputImage, options).then((result: Array<scanBarcode.ScanResult>) => {
                console.log("扫码结果", JSON.stringify(result));
              }).catch((error: BusinessError) => {
                console.log("扫码失败");
              });
            } catch (error) {
              console.log("扫码能力调用失败");
            }
          }).catch((error: BusinessError) => {
            console.log("图片选取失败");
          })
        });
    }
    .width('100%')
    .height('100%')
    .alignItems(HorizontalAlign.Center)
    .justifyContent(FlexAlign.Center)
  }
}

通过文本生成码图

码图生成能力支持将字符串转换为自定义格式的码图,包含条形码、二维码生成。可以将字符串转成联系人码图,手机克隆码图,例如将"HUAWEI"字符串生成码图使用。暂不支持模拟器使用,调用会返回错误信息“Emulator is not supported.”

码图生成业务流程:

1、用户向应用发起生成码请求后,输入需要生成的码的信息,包括码的类型、宽高等。
2、应用通过调用Scan Kit的createBarcode接口启动码图生成能力。
3、Scan Kit通过将字符串转换为所需格式的码图并返回给应用。
4、应用向用户返回生成码结果。

调用码图生成能力的createBarcode接口实现码图生成,通过 Promise方式回调,获取生成的码图,并通过pixelMap进行预览展示。

import { scanCore, generateBarcode } from '@kit.ScanKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { image } from '@kit.ImageKit';

@Entry
@Component
struct Index {
  @State pixelMap: image.PixelMap | undefined = undefined

  build() {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
      Button("码图生成").onClick(() => {
        // 以QR码为例,码图生成参数
        this.pixelMap = undefined;
        let content: string = 'huawei';
        let options: generateBarcode.CreateOptions = {
          scanType: scanCore.ScanType.QR_CODE,
          height: 400,
          width: 400
        }
        try {
          // 码图生成接口,成功返回PixelMap格式图片
          generateBarcode.createBarcode(content, options).then((pixelMap: image.PixelMap) => {
            this.pixelMap = pixelMap;
          }).catch((error: BusinessError) => {
            console.log("码图生成失败", JSON.stringify(error));
          })
        } catch (error) {
          console.log("码图接口调用失败", JSON.stringify(error));
        }

      })
      // 获取生成码后显示
      if (this.pixelMap) {
        Image(this.pixelMap).width(300).height(300).objectFit(ImageFit.Contain)
      }
    }
    .width('100%')
    .height('100%')
  }
}