大家好,我是陈杨,8 年前端老兵转型鸿蒙开发,也是一名鸿蒙极客。从前端到鸿蒙,我靠的是 “三天上手 ArkTS” 的技术嗅觉,以及 “居安思危” 的转型魄力。这三年,我不玩虚的,封装了开源组件库「莓创图表」,拿过创新赛大奖,更带着团队上架了 11 款自研 APP,涵盖工具、效率、创意等多个领域。想体验我的作品?欢迎搜索体验:指令魔方、JLPT、REFLEX PRO、国潮纸刻、Wss 直连、ZenithDocs Pro、圣诞相册、CSS 特效

在指令魔方 APP 里,有个超实用的功能:用户拍下纸质文档、票据或者截图,APP 能自动提取里面的文字,直接生成可编辑的指令。比如拍下打印的待办清单,一键识别后就能转换成 APP 里的执行指令,不用手动打字。这个 “图文转文字” 的黑科技,核心就是鸿蒙 Core Vision Kit 里的通用文字识别能力(OCR)。今天就带大家一步步拆解,用通俗的语言和可复用的代码,教你快速落地这个功能。

一、先搞懂:鸿蒙 OCR 到底能做啥?

简单说,鸿蒙的通用文字识别就是 “让 APP 看懂图片里的字”—— 不管是相机拍的照片、图库存的截图,还是扫描的文档,它都能把里面的印刷体文字提取出来,变成可编辑的文本。

它的适用场景特别广,指令魔方里就用到了这些:

  1. 纸质指令电子化:用户拍下手写或印刷的指令清单,识别后直接导入 APP
  2. 票据信息提取:识别快递单、发票上的关键信息,生成对应的查询指令
  3. 截图文字提取:用户截下网页、聊天记录里的文字,识别后快速创建指令

而且它很抗造,图片有点倾斜(比如拍照时没拍正)、光线不好(比如在昏暗的房间里拍),或者背景复杂(比如文字在花纹纸上),都能准确识别。不过要注意,目前这个能力不支持模拟器,开发时得用真实设备测试。

二、核心逻辑:从 “选图” 到 “识别” 的 4 步走

想实现图片文字识别,流程其实很清晰,就 4 个关键步骤,指令魔方也是这么做的:

  1. 初始化 OCR 服务:打开识别功能的 “开关”,准备好识别所需的资源
  2. 选择图片:让用户从图库选图,或者直接拍照(本文以图库选图为例)
  3. 图片格式转换:把选中的图片转换成 OCR 能识别的 PixelMap 格式
  4. 调用识别接口:传入图片,等待识别结果,最后显示在页面上

三、实现代码

// 导入需要的工具包
import { textRecognition } from '@kit.CoreVisionKit';
import { image } from '@kit.ImageKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { fileIo } from '@kit.CoreFileKit';
import { photoAccessHelper } from '@kit.MediaLibraryKit';

@Entry
@Component
struct OcrTextExtractor {
  // 选中的图片(PixelMap格式,OCR只能识别这种格式)
  @State selectedImage: PixelMap | undefined = undefined;
  // 识别后的文字结果
  @State recognizedText: string = "识别结果会显示在这里...";
  // 图片资源对象
  private imageSource: image.ImageSource | undefined = undefined;

  // 第一步:页面加载时初始化OCR服务
  async aboutToAppear(): Promise<void> {
    const initResult = await textRecognition.init();
    hilog.info(0x0000, 'OcrDemo', `OCR服务初始化结果:${initResult}`);
  }

  // 页面销毁时释放OCR资源(避免占用内存)
  async aboutToDisappear(): Promise<void> {
    await textRecognition.release();
    hilog.info(0x0000, 'OcrDemo', 'OCR服务已释放');
  }

  build() {
    Column({ space: 20 }) {
      // 显示选中的图片
      Image(this.selectedImage)
        .objectFit(ImageFit.Contain) // 保持图片比例
        .height('50%')
        .width('90%')
        .border({ width: 2, color: 0x317AE7, radius: 8 })
        .backgroundColor('#F5F5F5')

      // 显示识别结果(支持复制)
      TextArea({
        placeholder: '识别结果会显示在这里...',
        text: this.recognizedText
      })
      .width('90%')
      .height('20%')
      .border({ width: 2, color: 0x317AE7, radius: 8 })
      .copyOption(CopyOptions.LocalDevice) // 允许本地复制

      // 选择图片按钮
      Button('从图库选择图片')
        .type(ButtonType.Capsule)
        .backgroundColor(0x317AE7)
        .fontColor(Color.White)
        .width('90%')
        .height(45)
        .onClick(() => this.selectImageFromGallery())

      // 开始识别按钮
      Button('开始提取文字')
        .type(ButtonType.Capsule)
        .backgroundColor(0x317AE7)
        .fontColor(Color.White)
        .width('90%')
        .height(45)
        .onClick(() => this.startTextRecognition())
    }
    .padding(20)
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }

  // 第二步:从图库选择图片
  private async selectImageFromGallery() {
    // 调用系统图库
    const photoPicker = new photoAccessHelper.PhotoViewPicker();
    try {
      const selectResult = await photoPicker.select({
        MIMEType: photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE, // 只选图片
        maxSelectNumber: 1 // 最多选1张
      });
      const imageUri = selectResult.photoUris[0]; // 获取选中图片的URI
      if (imageUri) {
        await this.loadImageToPixelMap(imageUri); // 转换图片格式
      }
    } catch (err: BusinessError | any) {
      hilog.error(0x0000, 'OcrDemo', `选图失败:${err.message}`);
      this.recognizedText = `选图失败:${err.message}`;
    }
  }

  // 第三步:将图片转换为OCR能识别的PixelMap格式
  private async loadImageToPixelMap(uri: string) {
    try {
      // 打开图片文件
      const file = await fileIo.open(uri, fileIo.OpenMode.READ_ONLY);
      // 创建图片资源对象
      this.imageSource = image.createImageSource(file.fd);
      // 转换为PixelMap格式
      this.selectedImage = await this.imageSource.createPixelMap();
      // 重置识别结果
      this.recognizedText = "已选中图片,点击「开始提取文字」按钮...";
    } catch (err: BusinessError | any) {
      hilog.error(0x0000, 'OcrDemo', `图片加载失败:${err.message}`);
      this.recognizedText = `图片加载失败:${err.message}`;
    }
  }

  // 第四步:调用OCR接口,提取图片中的文字
  private startTextRecognition() {
    // 先判断是否选中了图片
    if (!this.selectedImage) {
      this.recognizedText = "请先选择一张图片!";
      return;
    }

    // 配置识别参数:是否支持朝向检测(这里关闭,按需开启)
    const recognitionConfig: textRecognition.TextRecognitionConfiguration = {
      isDirectionDetectionSupported: false
    };

    // 传入图片和配置,调用识别接口
    textRecognition.recognizeText(
      { pixelMap: this.selectedImage }, // 待识别的图片
      recognitionConfig
    )
    .then((result: textRecognition.TextRecognitionResult) => {
      // 识别成功,显示结果
      this.recognizedText = result.value || "未识别到文字";
      hilog.info(0x0000, 'OcrDemo', `识别成功:${result.value}`);
    })
    .catch((error: BusinessError) => {
      // 识别失败,显示错误信息
      this.recognizedText = `识别失败:${error.message}(错误码:${error.code})`;
      hilog.error(0x0000, 'OcrDemo', `识别失败:${error.message},错误码:${error.code}`);
    });
  }
}

代码关键部分解析

  1. 初始化和释放资源:aboutToAppear 里初始化 OCR 服务,aboutToDisappear 里释放,避免内存泄漏,这是鸿蒙开发的好习惯。
  2. 图片选择:用 photoAccessHelper.PhotoViewPicker 调用系统图库,只能选图片,最多选 1 张,符合日常使用场景。
  3. 图片格式转换:OCR 只能识别 PixelMap 格式,所以要通过 image.createImageSource 把图片文件转换成这种格式。
  4. 识别配置:isDirectionDetectionSupported 控制是否检测图片朝向,关闭的话识别速度更快,开启后能更好处理倾斜严重的图片。

四、实战效果演示

给大家看看指令魔方里的实际使用流程,更直观:

  1. 打开指令魔方,添加文本识别指令相关指令,比如:访问相册+文本识别;
  2. 点击 “从图库选择图片”,选中一张打印有指令的图片(比如 “打开日历 -> 添加事件:鸿蒙开发学习”);
  3. 点击 “开始提取文字”,等待 1-2 秒,识别结果就会显示在文本框里;
  4. 点击文本框复制,或者直接点击 “生成指令”,APP 就会自动把识别到的文字转换成可执行的指令。

五、避坑指南:这些问题一定要注意

  1. 权限问题:不需要额外申请权限!调用系统图库和 OCR 服务,鸿蒙已经默认处理了权限,不用在配置文件里额外添加。
  2. 图片格式:只能识别 PixelMap 格式,不能直接传图片 URI,一定要做格式转换,不然会识别失败。
  3. 识别范围:目前只支持印刷体文字,手写体识别率不高,开发时要给用户提示 “建议拍摄印刷体文字”。
  4. 设备支持:不支持模拟器,必须用真实的鸿蒙设备测试,不然会报 “服务不可用” 的错误。
  5. 错误处理:常见错误比如 “未选中图片”“图片损坏”“OCR 服务初始化失败”,都要在代码里做判断,给用户友好的提示,不要让 APP 崩溃。

六、数据安全:用户的图片和文字怎么处理?

和之前讲的 Core Speech Kit 一样,鸿蒙 OCR 在数据安全上也很让人放心:

  • 识别过程在本地完成:用户的图片和识别后的文字不会上传到云端,全程在设备本地处理;
  • 不存储用户数据:OCR 服务只在识别时临时使用图片数据,识别完成后不会留存,保护用户隐私。

指令魔方在隐私政策里也明确说明了这一点,让用户知道自己的图片和文字不会被泄露,用着更放心。

七、开发总结:新手也能快速落地

鸿蒙的通用文字识别能力上手特别简单,核心就是 “初始化 -> 选图 -> 转格式 -> 调用接口”,代码逻辑很固定,复制上面的代码,改改按钮文字、调整一下布局,就能集成到自己的 APP 里。

如果想扩展功能,还可以加这些:

  1. 拍照识别:在 “选择图片” 之外,加一个 “拍照” 按钮,调用相机实时拍照后直接识别;
  2. 文字编辑:识别后允许用户修改文本,比如纠正少量识别错误;
  3. 功能联动:像指令魔方一样,把识别后的文字和 APP 的核心功能联动,生成指令、保存笔记等。

如果你也在做鸿蒙 APP,需要图文转文字功能,直接用上面的代码试试~ 有问题欢迎留言交流,也可以下载指令魔方 APP,体验实际的 OCR 识别效果!

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐