HarmonyOS 鸿蒙Next解锁信息新维度:一款基于库读模式的通用文字识别功能

发布于 1周前 作者 h691938207 来自 鸿蒙OS

HarmonyOS 鸿蒙Next解锁信息新维度:一款基于库读模式的通用文字识别功能
<markdown _ngcontent-xux-c237="" class="markdownPreContainer">

能力介绍与使用场景

通用文字识别技术,简单来说,就是通过拍摄或扫描的方式,将票据、证件、表格、报纸、书籍等印刷品上的文字转化为图像信息。然后,这项技术会利用先进的文字识别算法,将这些图像信息进一步转化为计算机和其他设备能够理解和处理的字符信息。 这项技术的应用范围非常广泛。例如,你可以对文档、街景等进行翻拍,然后利用它来检测和识别图片中的文字。此外,这项技术还可以集成到其他应用程序中,提供文字检测和识别功能。根据识别结果,它还能提供翻译、搜索等相关服务。 无论是来自相机、图库还是其他来源的图像数据,这项技术都能处理。它具备自动检测文本、识别图像中文本位置以及文本内容的功能,这是一种开放的能力。 值得一提的是,这项技术在处理文本时具有很强的适应性。无论是文本倾斜、拍摄角度倾斜,还是复杂的光照条件和文本背景,它都能在这些特定场景下实现精准的文字识别。

图识文字-库读

开发步骤

要顺利使用通用文字识别技术,请遵循以下步骤进行设置和配置:

  1. 模块JSON中注册能力标识信息:在 src/main/module.json5 配置requestPermissions节点中,标识当前应用需要的能力集合用于扫读的准备
    "requestPermissions": [
     {
    "name": "ohos.permission.CAMERA",
    "usedScene": {
      "abilities": [
        "EntryAbility"
      ],
      "when": "inuse"
    },
    "reason": "CAMERA"
     },
    ]
    <button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
  2. 添加相关类至工程文件:首先,将负责文字识别的相关类导入到你的工程项目中。
    // 导入文本识别工具类
    import { textRecognition } from '@kit.CoreVisionKit'
    <button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
  3. 配置用户界面布局:简单地设计一个用户界面,包括为按钮组件添加点击事件,以便用户可以选择图片。
    Button('选择图片')
     .type(ButtonType.Capsule)
     .fontColor(Color.White)
     .alignSelf(ItemAlign.Center)
     .width('80%')
     .margin(10)
     .onClick(() => {
    // 拉起图库,获取图片资源
    this.selectImage();
     })
    <button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
  4. 获取并转换图片资源:当用户从图库中选取一张图片后,获取该图片并将其转换成PixelMap格式。
    private async selectImage() {
      let uri = await this.openPhoto();
      if (uri === undefined) {
        hilog.error(0x0000, 'StoreRead', "Failed to get uri.");
        return;
      }
      this.loadImage(uri);
    }
    

    private openPhoto(): Promise<string> { return new Promise<string>((resolve) => { let photoPicker = new picker.PhotoViewPicker(); photoPicker.select({ MIMEType: picker.PhotoViewMIMETypes.IMAGE_TYPE, maxSelectNumber: 1 }).then((res: picker.PhotoSelectResult) => { resolve(res.photoUris[0]); }).catch((err: BusinessError) => { hilog.error(0x0000, ‘StoreRead’, </span></span><span class="javascript"><span class="hljs-function"><span class="hljs-params"><span class="javascript">Failed to get photo image uri. code:${err.code},message:${err.message}</span></span></span></span><span class="hljs-function"><span class="hljs-params">); resolve(’’); }) }) }

    private loadImage(name: string) { setTimeout(async () => { let imageSource: image.ImageSource | undefined = undefined; let fileSource = await fileIo.open(name, fileIo.OpenMode.READ_ONLY); imageSource = image.createImageSource(fileSource.fd); this.chooseImage = await imageSource.createPixelMap(); }, 100) } <button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>

  5. 创建VisionInfo实例:实例化一个VisionInfo对象,并将包含待识别文字的PixelMap传入此对象。请注意,VisionInfo仅支持PixelMap类型的视觉信息。
    let visionInfo: textRecognition.VisionInfo = {
     pixelMap: this.chooseImage
    };
    <button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
  6. 设置文本识别配置:配置TextRecognitionConfiguration,这影响是否启用图片的朝向检测等选项。
    let textConfiguration: textRecognition.TextRecognitionConfiguration = {
     isDirectionDetectionSupported: false
    };
    <button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
  7. 执行文字识别处理:调用textRecognition.recognizeText方法,并根据返回的结果码进行处理—成功时返回0,失败则返回相应的错误码。该方法提供几种不同的调用方式,这里展示其中一种作为示例,其他方式参考官网API文档。 确保按照这些步骤操作,可以有效地实现通用文字识别功能。
    textRecognition.recognizeText(visionInfo, textConfiguration, (error: BusinessError, data: textRecognition.TextRecognitionResult) => {
      if (error.code !== 0) {
        hilog.error(0x0000, 'StoreRead', `Failed to recognize text. Code: ${error.code}, message: ${error.message}`);
        return;
      }
      // 识别成功,获取对象的结果
      let recognitionString = JSON.stringify(data);
      hilog.info(0x0000, 'StoreRead', `Succeeded in recognizing text:${recognitionString}`);
    

    // 将结果更新到Text中显示 this.dataValues = data.value;

    if(this.chooseImage && this.imageSource) { this.chooseImage.release(); this.imageSource.release(); } }); <button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>

PixelMap 对象

为了方便处理图像数据,我们引入了一个名为图像像素的类别。这个类别主要用于读取或写入图像数据,以及获取图像的相关信息。在开始使用图像像素类别的功能之前,我们需要通过createPixelMap的方法来创建一个新的PixelMap实例。 目前,PixelMap的序列化大小是有限制的,最大不能超过128MB。如果超过这个大小,程序会显示失败。计算大小的公式是:图像的宽度乘以高度再乘以每个像素点所占用的字节数。 从API版本11开始,PixelMap支持跨线程调用。也就是说,你可以在不同的线程中调用PixelMap的方法,这大大提高了程序的效率。但是,一旦你通过Worker将PixelMap跨线程后,原来线程中的PixelMap的所有接口都不能调用,否则会出现501错误,意味着服务器暂时不具备完成请求的功能。 在使用图像像素类别的方法前,我们需要通过image.createPixelMap的方法来构建一个PixelMap对象。这个对象就是我们进行图像处理的关键。

VisionInfo 对象

在处理视觉信息进行识别时,目前只接受颜色数据格式为rgba_8888的pixelmap类型。这种格式能够提供丰富的颜色信息,确保识别过程的准确性和效率。 recognizaText 对象的三种调用形式

  1. recognizeText(visionInfo: VisionInfo, callback: AsyncCallback): void
  • 识别视觉信息内包含的文本。使用Callback方式异步返回结果。
  • 参数情况
    • visionInfo:待识别的视觉信息;
    • 回调函数,返回文字识别的对象;
  1. recognizeText(visionInfo: VisionInfo, configuration?: TextRecognitionConfiguration): Promise
  • 识别视觉信息内包含的文本。使用Promise方式异步返回结果。
  • 参数情况
    • visionInfo:待识别的视觉信息;
    • configuration:识别的配置项;
    • 返回值:Promise对象,返回文字识别的结果对象;
  1. recognizeText(visionInfo: VisionInfo, configuration: TextRecognitionConfiguration, callback: AsyncCallback): void
  • 识别视觉信息内包含的文本。使用Callback方式异步返回结果。
  • 参数情况
    • visionInfo:待识别的视觉信息;
    • configuration:识别的配置项;
    • callback:识别结果的回调,可以用于界面显示或交互;

完整实例代码

// Main UI and logic code 

// 导入文本识别工具类 import { textRecognition } from ‘@kit.CoreVisionKit’ // 导入图片处理工具类 import { image } from ‘@kit.ImageKit’; // 导入性能分析工具类 import { hilog } from ‘@kit.PerformanceAnalysisKit’; // 导入业务错误处理类 import { BusinessError } from ‘@kit.BasicServicesKit’; // 导入文件选择器和文件输入输出工具类 import { picker, fileIo } from ‘@kit.CoreFileKit’;

@Entry @Component struct Index { // 定义一个私有变量imageSource,联合类型为 image.ImageSource或undefined private imageSource: image.ImageSource | undefined = undefined;

// 使用@State装饰器声明一个名为chooseImage的状态变量,联合类型为 PixelMap 或 undefined @State chooseImage: PixelMap | undefined = undefined;

// 使用@State装饰器声明一个名为 dataValues 的状态变量,类型为字符串 @State dataValues: string = ‘’;

build() { Column() { Image(this.chooseImage) .objectFit(ImageFit.Fill) .height(‘60%’)

 Text(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.dataValues.length &gt; <span class="hljs-number"><span class="hljs-number">0</span></span> ? `<span class="javascript"><span class="javascript">识别的文字:${</span><span class="hljs-keyword"><span class="javascript"><span class="hljs-keyword">this</span></span></span><span class="javascript">.dataValues}</span></span>` : <span class="hljs-string"><span class="hljs-string">''</span></span>)
   .copyOption(CopyOptions.LocalDevice)
   .height(<span class="hljs-string"><span class="hljs-string">'15%'</span></span>)
   .margin(<span class="hljs-number"><span class="hljs-number">10</span></span>)
   .width(<span class="hljs-string"><span class="hljs-string">'60%'</span></span>)
   .copyOption(CopyOptions.LocalDevice)
   .height(<span class="hljs-string"><span class="hljs-string">'15%'</span></span>)
   .margin(<span class="hljs-number"><span class="hljs-number">10</span></span>)
   .width(<span class="hljs-string"><span class="hljs-string">'60%'</span></span>)

 Button(<span class="hljs-string"><span class="hljs-string">'选择图片'</span></span>)
   .type(ButtonType.Capsule)
   .fontColor(Color.White)
   .alignSelf(ItemAlign.Center)
   .width(<span class="hljs-string"><span class="hljs-string">'80%'</span></span>)
   .margin(<span class="hljs-number"><span class="hljs-number">10</span></span>)
   .onClick<span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(() =&gt; {
     </span></span><span class="hljs-regexp"><span class="hljs-function"><span class="hljs-params"><span class="hljs-regexp">//</span></span></span></span><span class="hljs-function"><span class="hljs-params"> 拉起图库,获取图片资源
     </span></span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-params"><span class="hljs-keyword">this</span></span></span></span><span class="hljs-function"><span class="hljs-params">.selectImage();
   })</span></span></span><span class="hljs-function">

 </span><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">Button</span></span></span><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span><span class="hljs-string"><span class="hljs-function"><span class="hljs-params"><span class="hljs-string">'开始识别'</span></span></span></span><span class="hljs-function"><span class="hljs-params">)</span></span></span><span class="hljs-function">
   .</span><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">type</span></span></span><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(ButtonType.Capsule)</span></span></span><span class="hljs-function">
   .</span><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">fontColor</span></span></span><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(Color.White)</span></span></span><span class="hljs-function">
   .</span><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">alignSelf</span></span></span><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(ItemAlign.Center)</span></span></span><span class="hljs-function">
   .</span><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">width</span></span></span><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span><span class="hljs-string"><span class="hljs-function"><span class="hljs-params"><span class="hljs-string">'80%'</span></span></span></span><span class="hljs-function"><span class="hljs-params">)</span></span></span><span class="hljs-function">
   .</span><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">margin</span></span></span><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span><span class="hljs-number"><span class="hljs-function"><span class="hljs-params"><span class="hljs-number">10</span></span></span></span><span class="hljs-function"><span class="hljs-params">)</span></span></span><span class="hljs-function">
   .</span><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">onClick</span></span></span><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(async () =&gt; {
     </span></span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-params"><span class="hljs-keyword">this</span></span></span></span><span class="hljs-function"><span class="hljs-params">.textRecognitionTest();
   })</span></span></span><span class="hljs-function">

} .width(‘100%’) .height(‘100%’) .justifyContent(FlexAlign.Center) }

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’, </span></span><span class="javascript"><span class="hljs-function"><span class="hljs-params"><span class="javascript">Succeeded </span></span></span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-params"><span class="javascript"><span class="hljs-keyword">in</span></span></span></span></span><span class="hljs-function"><span class="hljs-params"><span class="javascript"> recognizing text:${recognitionString}</span></span></span></span><span class="hljs-function"><span class="hljs-params">); // 将结果更新到Text中显示 this.dataValues = data.value; if(this.chooseImage && this.imageSource) { this.chooseImage.release(); this.imageSource.release(); } }) .catch((error: BusinessError) => { hilog.error(0x0000, ‘OCRDemo’, </span></span><span class="javascript"><span class="hljs-function"><span class="hljs-params"><span class="javascript">Failed to recognize text. Code: ${error.code}, message: ${error.message}</span></span></span></span><span class="hljs-function"><span class="hljs-params">); this.dataValues = </span></span><span class="javascript"><span class="hljs-built_in"><span class="hljs-function"><span class="hljs-params"><span class="javascript"><span class="hljs-built_in">Error</span></span></span></span></span><span class="hljs-function"><span class="hljs-params"><span class="javascript">: ${error.message}</span></span></span></span><span class="hljs-function"><span class="hljs-params">; }); }

// 异步选择图片方法 private async selectImage() { let uri = await this.openPhoto(); // 调用打开图片的方法,获取图片的URI if (uri === undefined) { // 如果获取不到图片的URI,则输出错误日志并返回 hilog.error(0x0000, ‘StoreRead’, “Failed to get uri.”); return; } this.loadImage(uri); // 加载图片 }

// 打开图片的方法,返回Promise对象 private openPhoto(): Promise<string> { return new Promise<string>((resolve) => { let photoPicker = new picker.PhotoViewPicker(); // 创建图片选择器对象 photoPicker.select({ // 设置选择图片的条件 MIMEType: picker.PhotoViewMIMETypes.IMAGE_TYPE, // 只允许选择图片类型 maxSelectNumber: 1 // 最多选择一个图片 }).then((res: picker.PhotoSelectResult) => { // 成功选择图片后的回调函数 resolve(res.photoUris[0]); // 返回选中的图片的URI }).catch((err: BusinessError) => { // 选择图片失败后的回调函数 hilog.error(0x0000, ‘OCRDemo’, </span></span><span class="javascript"><span class="hljs-function"><span class="hljs-params"><span class="javascript">Failed to get photo image uri. Code:${err.code},message:${err.message}</span></span></span></span><span class="hljs-function"><span class="hljs-params">); // 输出错误日志 resolve(’’); // 返回空字符串 }) }) }

// 加载图片的方法 private loadImage(name: string) { setTimeout(async () => { // 使用setTimeout延迟执行,避免阻塞UI线程 let fileSource = await fileIo.open(name, fileIo.OpenMode.READ_ONLY); // 打开文件 this.imageSource = image.createImageSource(fileSource.fd); // 创建图片源 this.chooseImage = await this.imageSource.createPixelMap(); // 创建像素映射 }, 100) } } <button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>

实现效果

使用前 使用后
</markdown>
2 回复

HarmonyOS 鸿蒙的Next解锁信息新维度,其通用文字识别功能基于库读模式,旨在提升信息处理的智能化与效率。该功能可能通过集成先进的OCR(光学字符识别)技术,实现对多种文档、图片中文字的快速、准确识别与提取。开发者可借此功能优化应用体验,如文档管理、笔记应用等场景下的自动文本录入与编辑。确保应用已适配鸿蒙最新API,并检查相关权限设置。如果问题依旧没法解决请加我微信,我的微信是itying888。

回到顶部