之前做小程序或者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');
}