轻松上手-识图文字朗读

news/2024/10/18 13:17:42
作者:狼哥
团队:坚果派
团队介绍:坚果派由坚果等人创建,团队拥有12个华为HDE带领热爱HarmonyOS/OpenHarmony的开发者,以及若干其他领域的三十余位万粉博主运营。专注于分享HarmonyOS/OpenHarmony、ArkUI-X、元服务、仓颉。团队成员聚集在北京,上海,南京,深圳,广州,宁夏等地,目前已开发鸿蒙原生应用,三方库60+,欢迎交流。

介绍

​ 本案例旨在介绍一种创新的图像识别与语音合成技术,专注于将图片中的文字内容精准识别并转化为可听的语音输出。通过集成先进的OCR(光学字符识别)技术和TTS(文本到语音)转换技术,本方案能够迅速捕捉图片中的文字信息,无论是文档扫描、书籍页面还是路标指示,都能实现高效准确的识别。随后,利用智能语音合成技术,将识别出的文字流畅地朗读出来,为视觉障碍人士、阅读不便者以及需要高效信息获取的用户提供极大便利。该技术不仅拓宽了信息获取的渠道,还极大地提升了信息处理的效率和用户体验,是现代智能科技助力生活品质提升的典型应用。

效果预览

知识点

1. Picker(选择器)
2. textRecognition(文字识别)
3. textToSpeech (文本转语音)

工程目录

├──entry/src/main/ets                         // 代码区
│  ├──entryability
│  │  └──EntryAbility.ets 
│  ├──pages
│  │  └──Index.ets                            // 首页
│  └──utils
│     ├──ImageUtils.ets                       // 图片操作
│     └──Speaker.ets                      	  // 文字朗读操作
└──entry/src/main/resources                   // 应用资源目录

具体实现

下面介绍一下如何实现识别图片文字,并朗读识别出来的文字,我习惯把逻辑功能放到单独的文件里,在界面上调用,这样UI和逻辑分开,从工程目录可以看出,Index.ets文件是负责UI的,ImageUtils.ets文件里包含两个funtion,一个是getChooseImage从图库选择图片并返回,一个是readImage2Text把参数图片里的文字识别出来并返回,Speaker.ets文件是文字转语音的逻辑,包含创建对象,调用播放、暂停接口。

1. 图片选择

选择器(Picker)是一个封装PhotoViewPicker、DocumentViewPicker、AudioViewPicker等API模块,具有选择与保存的能力。应用可以自行选择使用哪种API实现文件选择和文件保存的功能。该类接口,需要应用在界面UIAbility中调用,否则无法拉起photoPicker应用或FilePicker应用。

export function getChooseImage():Promise<PixelMap> {return new Promise((resolve, reject) => {let imageSource: image.ImageSource | undefined = undefined;let chooseImage: PixelMap | undefined = undefined;// 将图片转换为PixelMap,可以通过图库获取let photoPicker = new picker.PhotoViewPicker();photoPicker.select({MIMEType: picker.PhotoViewMIMETypes.IMAGE_TYPE, maxSelectNumber: 1}).then((res: picker.PhotoSelectResult) => {let uri = res.photoUris[0];if (uri === undefined) {console.error('OCRDemo', "Failed to get uri.");return;}setTimeout(async () => {let fileSource = await fileIo.open(uri, fileIo.OpenMode.READ_ONLY);imageSource = image.createImageSource(fileSource.fd);chooseImage = await imageSource.createPixelMap();console.info('OCRDemo', `chooseImage Success`);resolve(chooseImage);}, 100)}).catch((err: BusinessError) => {console.error('OCRDemo', `Failed to get photo image uri. Code:${err.code},message:${err.message}`);}).finally(() => {if(chooseImage && imageSource) {chooseImage.release();imageSource.release();}})});
}
2. 识图文字

通用文字识别服务提供图像信息转换为字符信息的能力。通过拍照、扫描等光学输入方式,把各种票据、卡证、表格、报刊、书籍等印刷品文字转化为图像信息,再利用文字识别技术将图像信息转化为计算机等设备可以使用的字符信息,便于用户提取字符内容、屏幕坐标及外框。目前本服务支持识别的语言有:简体中文、英文、日文、韩文、繁体中文五种语言。

export function readImage2Text(img: PixelMap):Promise<string> {return new Promise((resolve, reject) => {if (!img) {promptAction.showToast({message: '请先选择图片,才能识别图片哦!'})return;}// 调用文本识别接口let visionInfo: textRecognition.VisionInfo = {pixelMap: img};setTimeout(async () => {let recognitionResult = await textRecognition.recognizeText(visionInfo);// 识别成功,获取对应的结果let recognitionString = recognitionResult.value;console.info('OCRDemo', `Succeeded in recognizing text:${recognitionString}`);resolve(recognitionString);},100);});
}
3. 朗读文字

文本转语音服务提供将文本信息转换为语音并进行播报的能力,便于用户与设备进行互动,实现实时语音交互,文本播报。

export class Speaker {ttsEngine?: textToSpeech.TextToSpeechEngine;speakListener?: textToSpeech.SpeakListener;extraParam: Record<string, Object> = {"queueMode": 0,   // 播报模式,不传参时默认为0。0为排队模式播报,1为抢占模式播报"speed": 1,       // 合成音频播报时的语速,支持范围[0.5-2],不传参时默认为1"volume": 2,      // 合成音频播报时的音量,支持范围[0-2],不传参时默认为1"pitch": 1,       // 合成音频播报时的音调,支持范围[0.5-2],不传参时默认为1"languageContext": 'zh-CN',"audioType": "pcm","soundChannel": 3,  // 通道,参数范围0-16,整数类型,可参考音频流使用类型介绍来选择适合自己的音频场景。不传参时默认为3,语音助手通道"playType": 1       // 合成类型,不传参时默认为1。当该参数为0时表示仅合成不播报,返回音频流,为1时表示合成与播报不返回音频流};initParamsInfo: textToSpeech.CreateEngineParams = {language: 'zh-CN',    // 语种 (如zh-CN为中文)person: 0,            // 音色(如0为聆小珊女声音色)online: 1,            // 模式(在线、离线等)extraParams: {"style": 'interaction-broadcast', "locate": 'CN', "name": 'EngineName'} // 额外参数};speakParams: textToSpeech.SpeakParams = {requestId: Date.now().toString(),extraParams: this.extraParam};constructor() {this.initListener()this.createEngine()}/*** 初始化监听*/initListener() {this.speakListener = {// 开始播报回调onStart(requestId: string, response: textToSpeech.StartResponse) {},// 合成完成及播报完成回调onComplete(requestId: string, response: textToSpeech.CompleteResponse) {if (response.type === 1) {emitter.emit("eventId");}},// 停止播报回调onStop(requestId: string, response: textToSpeech.StopResponse) {if (response.type === 1) {emitter.emit("eventId");}},// 返回音频流onData(requestId: string, audio: ArrayBuffer, response: textToSpeech.SynthesisResponse) {},// 错误回调onError(requestId: string, errorCode: number, errorMessage: string) {}};}/*** 创建Engine*/createEngine() {try {textToSpeech.createEngine(this.initParamsInfo,(err: BusinessError, textToSpeechEngine: textToSpeech.TextToSpeechEngine) => {if (!err) {this.ttsEngine = textToSpeechEngine;this.ttsEngine.setListener(this.speakListener);} else {}});} catch (error) {let message = (error as BusinessError).message;let code = (error as BusinessError).code;}}/*** 播报参数内容* @param content*/startSpeak(content: string) {this.createEngine();this.ttsEngine?.speak(content, this.speakParams);}/*** 停止播报*/stopSpeak() {this.shutdownEngine();this.ttsEngine?.stop();}/*** 销毁引擎实例*/shutdownEngine() {this.ttsEngine?.shutdown();}
}
4. 界面布局

界面布局为垂直布局,最上面是两个按钮,水平布局,下来是选择图片后,预览图片,再下来是从图片识别出来的文字。

@Entry
@Component
struct Index {@State chooseImage: PixelMap | undefined = undefined;@State recognitionString: string = '';private speaker: Speaker = new Speaker();/*** 选择图片*/async onChooseImage() {this.chooseImage = await getChooseImage();}/*** 识别图片*/async onRecognition() {if (this.chooseImage) {this.recognitionString = await readImage2Text(this.chooseImage);// 朗读识别出来的文字this.speaker.startSpeak(this.recognitionString)}}build() {Column({ space: 10 }) {Row() {Button('选择图片').width(100).onClick(() => {this.onChooseImage()})Button('识字朗读').width(100).onClick(() => {this.onRecognition()})}.width('100%').height(50).justifyContent(FlexAlign.SpaceEvenly)Divider()Image(this.chooseImage).width('100%').objectFit(ImageFit.Contain)Divider()Text(this.recognitionString).lineHeight(25).width('100%').fontSize(18).backgroundColor('#ffd6d3d3')}.width('100%').height('100%').padding(20).justifyContent(FlexAlign.Start).alignItems(HorizontalAlign.Center)}
}

约束与限制

1.本示例仅支持标准系统上运行,支持设备:华为手机。

2.HarmonyOS系统:HarmonyOS NEXT Developer Beta1及以上。

3.DevEco Studio版本:DevEco Studio NEXT Developer Beta1及以上。

4.HarmonyOS SDK版本:HarmonyOS NEXT Developer Beta1 SDK及以上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/73027.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

mysql语法-DMLDQL

1.DML操作数据——添加、修改、删除 (1)添加数据:实例(2)修改数据实例注意:修改时如果update语句不加where条件,则会把表中所有数据都修改了! (3)删除数据:实例2.DQL查询 查询语法(1)基础查询:实例(2)条件查询:

免费使用AI写作助手,为你轻松打造爆款文章

在当今内容为王的时代,一篇高质量的文章能够迅速抓住读者的眼球,提升个人或品牌的曝光度。但对于许多创作者而言,灵感枯竭和写作效率低下是常见的挑战。此时,免费AI写作助手的出现,为解决这些问题提供了新的可能性。以下是这款AI写作助手的独特魅力和使用指南。一、AI写作…

从组合优化问题建模到贪心法求解以简单调度为例

此为课题组所指导本科生和低年级硕士生学习组合优化问题汇报 所用教材:北京大学屈婉玲教授《算法设计与分析》 课程资料:https://www.icourse163.org/course/PKU-1002525003 承诺不用于任何商业用途,仅用于学术交流和分享更多内容请关注课题组官方中文主页:https://JaywayX…

python: invalid value encountered in divide以及invalid value encountered in double_scalars报错

运行命令python eqtl_prepare_expression.py data.tpm.gct data.reads_count.gct --tpm_threshold 0.1 --count_threshold 2 --sample_frac_threshold 0.2 --normalization_method tmm --output data.txt时出现了报错“invalid value encountered in divide”以及“invalid val…

java报错大合集

​D:\代码\Mybatis-84\src\test\java\com\lu\TestNews.java:100:39 java: 找不到符号符号: 方法 of(int,int)位置: 接口 java.util.List解决idea中的jdk变成1..8了而List.of()是9出的所有报错,改回17 在“class java.lang.String”中没有名为“name”的属性的 getter纯属粗心…

DataDream:调一调更好,基于LoRA微调SD的训练集合成新方案 | ECCV24

尽管文本到图像的扩散模型已被证明在图像合成方面达到了最先进的结果,但它们尚未证明在下游应用中的有效性。先前的研究提出了在有限的真实数据访问下为图像分类器训练生成数据的方法。然而,这些方法在生成内部分布图像或描绘细粒度特征方面存在困难,从而阻碍了在合成数据集…

深入理解浮点数的表示

浮点数的表示 通常,浮点数表示为: \[N = (-1)^{S} \times M \times R^{E} \]其中,S取值为0或者1,用来决定浮点数的符号;M是一个二进制定点小数,称为尾数,一般用定点原码小数表示;E是一个二进制顶点整数,称为阶码或者指数,用移码表示。R是基数(隐含),可以约定为2、4、…