端侧OCR文字识别实现 -- Core Vision Kit ##HarmonyOS SDK AI##

2025-06-02 21:10:36
152次阅读
0个评论

​ 之前做小程序或者web的时候,对于OCR相关的功能,都是调用三方接口实现的,例如百度的ocr接口,整体的流程较为复杂,需要先通过后端代码获取百度的token,然后本地选择图片,图片发送到服务器获取图片url,把这个url和token再发给百度的ocr接口获取识别数据……或者图片转base64以后把这个base64发给接口,然而鸿蒙这里,目前我也不知道啥原因(可能是发送请求的数据长度有限制),我发送出去的base64是不全的。

总之,传统方法做ocr流程上比较复杂,而原生鸿蒙开发提供了端侧AI的能力,其中就包括了“Core Vision Kit(基础视觉服务)”,即与图片识别相关的AI能力,使用场景中就包括了“通用文字识别”,即我们前文中所说的ocr功能。

其整体流程概括为:

首先通过各种方法得到一张图片,例如拍照、从相册中选择、甚至你也可以通过canvas画布生成的图片或者通过组件截图获取的图片等等……只要是一张图片。接着把图片转成图片转换为PixelMap格式,实例化VisionInfo对象,并传入待检测图片的PixelMap。最后调用textRecognition的recognizeText接口,对识别到的结果进行处理。其中还有一步, 即配置通用文本识别的配置项TextRecognitionConfiguration,用于配置是否支持朝向检测,这一点其实可以不用管,因为你在开发的时候,是完全没有办法确定到时候实际操作中,到底是不是正向的。

另外还有一点要注意的,就是在完成以后,要释放OCR服务,这一点在textRecognition的文档里有提及,对于释放这一步,并不是说每一次OCR结束以后都要释放,而是可以在这个页面aboutToDisAppear的时候去释放

每一步的代码如下:

选择图片:

private async selectImage() {
    let uri = await this.openPhoto();
    if (uri === undefined) {
      hilog.error(0x0000, 'OCRDemo', "Failed to get uri.");
      return;
    }
    this.loadImage(uri);
  }

  private openPhoto(): Promise<string> {
    return new Promise<string>((resolve) => {
      let photoPicker: photoAccessHelper.PhotoViewPicker = new photoAccessHelper.PhotoViewPicker();
      photoPicker.select({
        MIMEType: photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE,
        maxSelectNumber: 1
      }).then((res: photoAccessHelper.PhotoSelectResult) => {
        resolve(res.photoUris[0]);
      }).catch((err: BusinessError) => {
        hilog.error(0x0000, 'OCRDemo', `Failed to get photo image uri. code: ${err.code}, message: ${err.message}`);
        resolve('');
      })
    })
  }

转PixelMap格式

private loadImage(name: string) {
    setTimeout(async () => {
      let fileSource = await fileIo.open(name, fileIo.OpenMode.READ_ONLY);
      this.imageSource = image.createImageSource(fileSource.fd);
      this.chooseImage = await this.imageSource.createPixelMap();
    }, 100)
  }

OCR识别

private textRecognitionTest() {
    if (!this.chooseImage) {
      return;
    }
    // 调用文本识别接口
    let visionInfo: textRecognition.VisionInfo = {
      pixelMap: this.chooseImage
    };
    let textConfiguration: textRecognition.TextRecognitionConfiguration = {
      isDirectionDetectionSupported: false
    };
    textRecognition.recognizeText(visionInfo, textConfiguration)
      .then((data: textRecognition.TextRecognitionResult) => {
        // 识别成功,获取对应的结果
        let recognitionString = JSON.stringify(data);
        hilog.info(0x0000, 'OCRDemo', `Succeeded in recognizing text:${recognitionString}`);
        // 将结果更新到Text中显示
        this.dataValues = data.value;
      })
      .catch((error: BusinessError) => {
        hilog.error(0x0000, 'OCRDemo', `Failed to recognize text. Code: ${error.code}, message: ${error.message}`);
        this.dataValues = `Error: ${error.message}`;
      });
  }

最后资源释放

 async aboutToDisappear(): Promise<void> {
    await textRecognition.release();
    hilog.info(0x0000, 'OCRDemo', 'OCR service released successfully');
  }

收藏00

登录 后评论。没有帐号? 注册 一个。