华为HarmonyOS 快速构建各种文本识别应用 -- 通用文字识别

适用场景

通用文字识别,是通过拍照、扫描等光学输入方式,将各种票据、卡证、表格、报刊、书籍等印刷品文字转化为图像信息,再利用文字识别技术将图像信息转化为计算机等设备可以使用的字符信息的技术。

  • 可以对文档翻拍、街景翻拍等图片进行文字检测和识别,也可以集成于其他应用中,提供文字检测、识别的功能,并根据识别结果提供翻译、搜索等相关服务。
  • 可以处理来自相机、图库等多种来源的图像数据,提供一个自动检测文本、识别图像中文本位置以及文本内容功能的开放能力。
  • 支持特定角度范围内的文本倾斜、拍摄角度倾斜、复杂光照条件以及复杂文本背景等场景的文字识别。

开发步骤

  1. 在使用通用文字识别时,将实现文字识别的相关的类添加至工程。

    复制代码
    1. import { textRecognition } from '@kit.CoreVisionKit';
  2. 简单配置页面的布局,并在Button组件添加点击事件,拉起图库,选择图片。

    复制代码
    1. Button('选择图片')
    2. .type(ButtonType.Capsule)
    3. .fontColor(Color.White)
    4. .alignSelf(ItemAlign.Center)
    5. .width('80%')
    6. .margin(10)
    7. .onClick(() => {
    8. // 拉起图库,获取图片资源
    9. this.selectImage();
    10. })
  3. 通过图库获取图片资源,将图片转换为PixelMap,并添加初始化和释放方法。

    复制代码
    1. async aboutToAppear(): Promise<void> {
    2. const initResult = await textRecognition.init();
    3. hilog.info(0x0000, 'OCRDemo', `OCR service initialization result:${initResult}`);
    4. }
    5. async aboutToDisappear(): Promise<void> {
    6. await textRecognition.release();
    7. hilog.info(0x0000, 'OCRDemo', 'OCR service released successfully');
    8. }
    9. private async selectImage() {
    10. let uri = await this.openPhoto();
    11. if (uri === undefined) {
    12. hilog.error(0x0000, 'OCRDemo', "Failed to get uri.");
    13. return;
    14. }
    15. this.loadImage(uri);
    16. }
    17. private openPhoto(): Promise<string> {
    18. return new Promise<string>((resolve) => {
    19. let photoPicker: photoAccessHelper.PhotoViewPicker = new photoAccessHelper.PhotoViewPicker();
    20. photoPicker.select({
    21. MIMEType: photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE,
    22. maxSelectNumber: 1
    23. }).then((res: photoAccessHelper.PhotoSelectResult) => {
    24. resolve(res.photoUris[0]);
    25. }).catch((err: BusinessError) => {
    26. hilog.error(0x0000, 'OCRDemo', `Failed to get photo image uri. code:{err.code},message:{err.message}`);
    27. resolve('');
    28. })
    29. })
    30. }
    31. private loadImage(name: string) {
    32. setTimeout(async () => {
    33. let imageSource: image.ImageSource | undefined = undefined;
    34. let fileSource = await fileIo.open(name, fileIo.OpenMode.READ_ONLY);
    35. imageSource = image.createImageSource(fileSource.fd);
    36. this.chooseImage = await imageSource.createPixelMap();
    37. }, 100)
    38. }
  4. 实例化VisionInfo对象,并传入待检测图片的PixelMap

    VisionInfo为待OCR检测识别的入参项,目前仅支持PixelMap类型的视觉信息。

    复制代码
    1. let visionInfo: textRecognition.VisionInfo = {
    2. pixelMap: this.chooseImage
    3. };
  5. 配置通用文本识别的配置项TextRecognitionConfiguration,用于配置是否支持朝向检测。

    复制代码
    1. let textConfiguration: textRecognition.TextRecognitionConfiguration = {
    2. isDirectionDetectionSupported: false
    3. };
  6. 调用textRecognition的recognizeText接口,对识别到的结果进行处理。

    当调用成功时,获取文字识别的结果;调用失败时,将返回对应错误码。
    recognizeText接口提供了三种调用形式,当前以其中一种作为示例,其他方式可参考API文档

    复制代码
    1. textRecognition.recognizeText(visionInfo, textConfiguration)
    2. .then((data: textRecognition.TextRecognitionResult) => {
    3. // 识别成功,获取对应的结果
    4. let recognitionString = JSON.stringify(data);
    5. hilog.info(0x0000, 'OCRDemo', `Succeeded in recognizing text:${recognitionString}`);
    6. // 将结果更新到Text中显示
    7. this.dataValues = data.value;
    8. })
    9. .catch((error: BusinessError) => {
    10. hilog.error(0x0000, 'OCRDemo', `Failed to recognize text. Code: ${error.code}, message: ${error.message}`);
    11. this.dataValues = `Error: ${error.message}`;
    12. });

开发实例

点击按钮,识别一张图片的文字内容,并通过日志打印。

复制代码
  1. import { textRecognition } from '@kit.CoreVisionKit'
  2. import { image } from '@kit.ImageKit';
  3. import { hilog } from '@kit.PerformanceAnalysisKit';
  4. import { BusinessError } from '@kit.BasicServicesKit';
  5. import { fileIo } from '@kit.CoreFileKit';
  6. import { photoAccessHelper } from '@kit.MediaLibraryKit';
  7. @Entry
  8. @Component
  9. struct Index {
  10. private imageSource: image.ImageSource | undefined = undefined;
  11. @State chooseImage: PixelMap | undefined = undefined;
  12. @State dataValues: string = '';
  13. async aboutToAppear(): Promise<void> {
  14. const initResult = await textRecognition.init();
  15. hilog.info(0x0000, 'OCRDemo', `OCR service initialization result:${initResult}`);
  16. }
  17. async aboutToDisappear(): Promise<void> {
  18. await textRecognition.release();
  19. hilog.info(0x0000, 'OCRDemo', 'OCR service released successfully');
  20. }
  21. build() {
  22. Column() {
  23. Image(this.chooseImage)
  24. .objectFit(ImageFit.Fill)
  25. .height('60%')
  26. Text(this.dataValues)
  27. .copyOption(CopyOptions.LocalDevice)
  28. .height('15%')
  29. .margin(10)
  30. .width('60%')
  31. Button('选择图片')
  32. .type(ButtonType.Capsule)
  33. .fontColor(Color.White)
  34. .alignSelf(ItemAlign.Center)
  35. .width('80%')
  36. .margin(10)
  37. .onClick(() => {
  38. // 拉起图库,获取图片资源
  39. this.selectImage();
  40. })
  41. Button('开始识别')
  42. .type(ButtonType.Capsule)
  43. .fontColor(Color.White)
  44. .alignSelf(ItemAlign.Center)
  45. .width('80%')
  46. .margin(10)
  47. .onClick(async () => {
  48. this.textRecognitionTest();
  49. })
  50. }
  51. .width('100%')
  52. .height('100%')
  53. .justifyContent(FlexAlign.Center)
  54. }
  55. private textRecognitionTest() {
  56. if (!this.chooseImage) {
  57. return;
  58. }
  59. // 调用文本识别接口
  60. let visionInfo: textRecognition.VisionInfo = {
  61. pixelMap: this.chooseImage
  62. };
  63. let textConfiguration: textRecognition.TextRecognitionConfiguration = {
  64. isDirectionDetectionSupported: false
  65. };
  66. textRecognition.recognizeText(visionInfo, textConfiguration)
  67. .then((data: textRecognition.TextRecognitionResult) => {
  68. // 识别成功,获取对应的结果
  69. let recognitionString = JSON.stringify(data);
  70. hilog.info(0x0000, 'OCRDemo', `Succeeded in recognizing text:${recognitionString}`);
  71. // 将结果更新到Text中显示
  72. this.dataValues = data.value;
  73. })
  74. .catch((error: BusinessError) => {
  75. hilog.error(0x0000, 'OCRDemo', `Failed to recognize text. Code: ${error.code}, message: ${error.message}`);
  76. this.dataValues = `Error: ${error.message}`;
  77. });
  78. }
  79. private async selectImage() {
  80. let uri = await this.openPhoto();
  81. if (uri === undefined) {
  82. hilog.error(0x0000, 'OCRDemo', "Failed to get uri.");
  83. return;
  84. }
  85. this.loadImage(uri);
  86. }
  87. private openPhoto(): Promise<string> {
  88. return new Promise<string>((resolve) => {
  89. let photoPicker: photoAccessHelper.PhotoViewPicker = new photoAccessHelper.PhotoViewPicker();
  90. photoPicker.select({
  91. MIMEType: photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE,
  92. maxSelectNumber: 1
  93. }).then((res: photoAccessHelper.PhotoSelectResult) => {
  94. resolve(res.photoUris[0]);
  95. }).catch((err: BusinessError) => {
  96. hilog.error(0x0000, 'OCRDemo', `Failed to get photo image uri. Code:{err.code},message:{err.message}`);
  97. resolve('');
  98. })
  99. })
  100. }
  101. private loadImage(name: string) {
  102. setTimeout(async () => {
  103. let fileSource = await fileIo.open(name, fileIo.OpenMode.READ_ONLY);
  104. this.imageSource = image.createImageSource(fileSource.fd);
  105. this.chooseImage = await this.imageSource.createPixelMap();
  106. }, 100)
  107. }
  108. }
相关推荐
鸿蒙开天组●1 小时前
鸿蒙实战篇-解决报错提示“code:9568305 error: dependent module does not exist”
华为·编辑器·harmonyos·鸿蒙
SuperHeroWu74 小时前
【HarmonyOS Next】拒绝权限二次申请授权处理
华为·harmonyos·授权·设置·弹框·二次申请权限·拒绝权限
m0_748232644 小时前
鸿蒙NEXT(五):鸿蒙版React Native架构浅析
react native·架构·harmonyos
东林知识库5 小时前
鸿蒙NEXT应用App测试-通用测试
华为·harmonyos
二川bro5 小时前
HarmonyOS Design 介绍
华为·harmonyos
码上为赢5 小时前
【DeepSeek与鸿蒙HarmonyOS:开启应用开发新次元】
华为·harmonyos·deepseek
Jack_Wee6 小时前
解锁鸿蒙装饰器:应用、原理与优势全解析
harmonyos
skywalk81637 小时前
PolyOS 是面向 RISC-V 架构的智能终端和 AIoT 开源操作系统(基于开源鸿蒙)
qemu·harmonyos·risc-v
二川bro7 小时前
HarmonyOS 开发套件 介绍——下篇
华为·harmonyos
繁依Fanyi8 小时前
巧妙实现右键菜单功能,提升用户操作体验
开发语言·前端·javascript·vue.js·uni-app·harmonyos