使用OneNote的COM组件,实现OCR功能。
背景
在业务系统开发的过程中,很多情况下会去识别图片中的相关信息,并且把信息录入到系统中。现在希望通过自动化的方式录入,就有了以下的工作。在对比了几个OCR软件在中文识别方面的准确率后,决定使用微软的OneNote开发相应的功能。
准备工作
- 安装OneNote 2010;(注:在 Microsoft Office 2003 中的工具组件中有一个“ Microsoft Office Document Imaging”的组件包,之后的Office版本将这个功能集成到OneNote中了)
- 查询网上相关OneNote的资料,真是少得可怜,即使找到现有的代码也是各种坑。
- 在OneNote中的图片识别功能如下图,把图片放到一个tab中,右键图片就会出现红框所标注的功能,这个是我需要在程序中来调用的:
代码实现的逻辑
- 获取图片的Base64编码;
- 开启OneNote程序,在一个空的newfile.one中,生成一个新的page;
- 此时,新的page页中,会有一个固定格式的xml,把图片的Base64编码,更新到对应的节点上;
- 更新节点后,会自动调用OCR的功能,把识别出来的文字,放入到固定节点上;
- 从识别出来的文字节点上,取出相应的文字就可以了;
- 彻底销毁当前的页面(如果不是彻底的话,这个newfile.one会越来越大);
public class OrcImage
{
private static readonly string tmpPath = AppDomain.CurrentDomain.BaseDirectory + "tmpPath/";
private static readonly int waitTime = Convert.ToInt32(ConfigurationManager.AppSettings["WaitTime"]); private Tuple<string, int, int> GetBase64(string strImgPath)
{
return GetBase64(new FileInfo(strImgPath));
} /// <summary>
/// 获取图片的Base64编码
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
private Tuple<string, int, int> GetBase64(FileInfo file)
{
using (MemoryStream ms = new MemoryStream())
{
Bitmap bp = new Bitmap(file.FullName);
switch (file.Extension.ToLower())
{
case ".jpg":
bp.Save(ms, ImageFormat.Jpeg);
break; case ".jpeg":
bp.Save(ms, ImageFormat.Jpeg);
break; case ".gif":
bp.Save(ms, ImageFormat.Gif);
break; case ".bmp":
bp.Save(ms, ImageFormat.Bmp);
break; case ".tiff":
bp.Save(ms, ImageFormat.Tiff);
break; case ".png":
bp.Save(ms, ImageFormat.Png);
break; case ".emf":
bp.Save(ms, ImageFormat.Emf);
break; default:
return new Tuple<string, int, int>("不支持的图片格式。", , );
}
byte[] buffer = ms.GetBuffer();
return new Tuple<string, int, int>(Convert.ToBase64String(buffer), bp.Width, bp.Height);
}
} public string Orc_Img(FileInfo fi)
{
// 向Onenote2010中插入图片
var onenoteApp = new Microsoft.Office.Interop.OneNote.Application(); //onenote提供的API
/***************************************************************************************/
string sectionID;
onenoteApp.OpenHierarchy(tmpPath + "newfile.one", null, out sectionID, CreateFileType.cftSection);
string pageID = "{A975EE72-19C3-4C80-9C0E-EDA576DAB5C6}{1}{B0}"; // 格式 {guid}{tab}{??}
onenoteApp.CreateNewPage(sectionID, out pageID, NewPageStyle.npsBlankPageNoTitle);
/********************************************************************************/
string notebookXml;
onenoteApp.GetHierarchy(null, HierarchyScope.hsPages, out notebookXml);
var doc = XDocument.Parse(notebookXml);
var ns = doc.Root.Name.Namespace;
var pageNode = doc.Descendants(ns + "Page").FirstOrDefault();
var existingPageId = pageNode.Attribute("ID").Value;
if (pageNode != null)
{
Tuple<string, int, int> imgInfo = this.GetBase64(fi);
var page = new XDocument(new XElement(ns + "Page",
new XElement(ns + "Outline",
new XElement(ns + "OEChildren",
new XElement(ns + "OE",
new XElement(ns + "Image",
new XAttribute("format", fi.Extension.Remove(, )), new XAttribute("originalPageNumber", ""),
new XElement(ns + "Position",
new XAttribute("x", ""), new XAttribute("y", ""), new XAttribute("z", "")),
new XElement(ns + "Size",
new XAttribute("width", imgInfo.Item2), new XAttribute("height", imgInfo.Item3)),
new XElement(ns + "Data", imgInfo.Item1)))))));
page.Root.SetAttributeValue("ID", existingPageId); onenoteApp.UpdatePageContent(page.ToString(), DateTime.MinValue); // 线程休眠时间,单位毫秒,若图片很大,则延长休眠时间,保证Onenote OCR完毕
int fileSize = Convert.ToInt32(fi.Length / / ); // 文件大小 单位M
System.Threading.Thread.Sleep(waitTime * (fileSize > ? fileSize : )); // 小于1M的都默认1M string pageXml;
onenoteApp.GetPageContent(existingPageId, out pageXml, PageInfo.piBinaryData); /*********************************************************************************/ XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(pageXml);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("one", ns.ToString()); XmlNode xmlNode = xmlDoc.SelectSingleNode("//one:Image//one:OCRText", nsmgr);
string strRet = xmlNode.InnerText; /**********************************************************************/ onenoteApp.DeleteHierarchy(sectionID, DateTime.MinValue, true); // 摧毁原始页面 return strRet;
} return "没有识别";
}
}
XML的格式
/*Onenote 2010 中图片的XML格式
<one:Image format="" originalPageNumber="0" lastModifiedTime="" objectID="">
<one:Position x="" y="" z=""/>
<one:Size width="" height=""/>
<one:Data>Base64</one:Data> //以下标签由Onenote 2010自动生成,不要在程序中处理,目标是获取OCRText中的内容。
<one:OCRData lang="en-US">
<one:OCRText>
<![CDATA[ OCR后的文字 ]]>
</one:OCRText>
<one:OCRToken startPos="0" region="0" line="0" x="4.251968383789062" y="3.685039281845092" width="31.18110275268555" height="7.370078563690185"/>
<one:OCRToken startPos="7" region="0" line="0" x="39.40157318115234" y="3.685039281845092" width="13.32283401489258" height="8.78740119934082"/>
<one:OCRToken startPos="12" region="0" line="1" x="4.251968383789062" y="17.85826683044434" width="23.52755928039551" height="6.803150177001953"/>
<one:OCRToken startPos="18" region="0" line="1" x="32.031494140625" y="17.85826683044434" width="41.10236358642578" height="6.803150177001953"/>
<one:OCRToken startPos="28" region="0" line="1" x="77.66928863525391" y="17.85826683044434" width="31.46456718444824" height="6.803150177001953"/>
................
</one:Image>
*/ /*ObjectID格式
The representation of an object to be used for identification of objects on a page. Not unique through OneNote, but unique on the page and the hierarchy.
<xsd:simpleType name="ObjectID" ">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\{[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\}\{[0-9]+\}\{[A-Z][0-9]+\}" />
</xsd:restriction>
</xsd:simpleType>
*/
目前是桌面应用程序是实现了相关功能。预期期望是:任何一个系统通过webservice接口形式就能使用OCR功能。但是改成一个web程序遇到了问题,在网上找了仅有的一点点资料,也没有解决。我了解到,现在使用OneNote的OCR功能的程序也都是用WinForm程序,在程序运行的过程中,会在后台启动OneNote程序。所以我猜测可能是由于这个原因,导致它只能做成桌面程序。
检索 COM 类工厂中 CLSID 为 {D7FAC39E-7FF1-49AA-98CF-A1DDD316337E} 的组件失败,原因是出现以下错误: 80070005 拒绝访问。 (异常来自 HRESULT:0x80070005 (E_ACCESSDENIED))。 web中报这个错误,是权限的问题。依照配置Excel,Word这类COM来找,可是发现DCOM中,一直都找不到这个ID的组件。知道的朋友麻烦告知一下,谢谢。
程序效果图如下:识别效果还不错,剩下的就是根据所需要的信息,进行正则表达式的匹配就可以了。
使用OneNote的COM组件,实现OCR功能。的更多相关文章
- 小试Office OneNote 2010的图片文字识别功能(OCR)
原文:小试Office OneNote 2010的图片文字识别功能(OCR) 自Office 2003以来,OneNote就成为了我电脑中必不可少的软件,它集各种创新功能于一身,可方便的记录下各种类型 ...
- 你知道OneNote的OCR功能吗?office lens为其增大威力,中文也识别
原文:[原创]你知道OneNote的OCR功能吗?office lens为其增大威力,中文也识别 OneNote提供了强大的从图片中取出文字的功能,大家只要装上了桌面版OneNote(本人用的2013 ...
- Azure 认知服务 (5) 计算机视觉API - 使用C#代码实现读取图片中的文字(OCR)功能
<Windows Azure Platform 系列文章目录> 在笔者之前的文章:Azure 认知服务 (4) 计算机视觉API - 读取图片中的文字 (OCR) 介绍了使用用户界面,在海 ...
- 042——VUE中组件之子组件使用$on与$emit事件触发父组件实现购物车功能
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 有道词典中的OCR功能:第三方库的变化
之前有点好奇有道词典中的OCR功能,具体来说就是强力取词功能.我知道的最有名的OCR库是tesseract,这个库是惠普在早些年前开源的. 在用python做爬虫处理验证码的时候,就会用到这个库,对应 ...
- 尝试用React写几个通用组件 - 带搜索功能的下拉列表,开关切换按钮,弹出框
尝试用React写几个通用组件 - 带搜索功能的下拉列表,开关切换按钮,弹出框 近期正在逐步摸索学习React的用法,尝试着写几个通用型的组件,整体项目还是根据webpack+react+css-me ...
- 基于Tesseract组件的OCR识别
基于Tesseract组件的OCR识别 背景以及介绍 欲研究C#端如何进行图像的基本OCR识别,找到一款开源的OCR识别组件.该组件当前已经已经升级到了4.0版本.和传统的版本(3.x)比,4.0时代 ...
- 【原创】你知道OneNote的OCR功能吗?office lens为其增大威力,中文也识别
OneNote提供了强大的从图片中取出文字的功能,大家只要装上了桌面版OneNote(本人用的2013版和win8.1版测试的,其他版本为测),将图片放在OneNote笔记中,右键图片即可把图片中的文 ...
- JavaMail组件实现邮件功能
实现邮件收发功能需要3个jar包: 1.JavaMail组件保内的mail.jar和smtp.jar包 2.JAF组件包里的activition.jar. 复制到WebRoot/WEB-INF/lib ...
随机推荐
- GridControl控件的数据显示的样式控制(转)
如上两图所示,Dev列表控件GridControl默认的格式并没有渐变变色效果,显示的日期数据,也是“yyyy-MM-dd”的格式,而非“yyyy-MM-dd HH:mm:ss”即使对于后面有长格式的 ...
- 问题解决——VS2010 将生成的文件复制到指定位置
我是从VC6直接过渡到VS2010的,VS2008没怎么用过.用VS2010的时候,每次生成dll后,手工把dll.lib..h文件复制到指定文件夹太麻烦了,所以着手写了这个. =========== ...
- jQuery form插件的使用--ajaxForm()和ajaxSubmit()的可选参数项对象
一.前提说明 Form Plugin API 里提供了很多有用的方法可以让你轻松的处理表单里的数据和表单的提交过程. 测试环境:部署到Tomcat中的web项目. 二.简单介绍 本文演示的是:jQue ...
- Github学习进阶-初露锋芒,通过命令行将本地git仓库推送到Github上面的仓库
前提: 1. 需要安装git 客户端. 能打开 git bash 命令行窗口. 2. 生成了ssh 秘钥,并添加到了Github上面. 一.在Github上面建立一个git仓库. 点击 + 号,在 ...
- iTOP-4412开发板---Linux系统学习下载步骤
本文转自迅为论坛:http://www.topeetboard.com 1.cd /home/topeet/Linux-simple/console 下建立.c文件 2. 编译命令,就在此目录下 # ...
- css shorthand属性简写
一.什么是shorthand 属性简写(shorthand)就是一次性声明一组相关的属性.好处呢当然是众所周知的,让css从臃肿无序升级为简洁有效具有高可读性. 大多数的人都使用属性简写,我也用,但是 ...
- uva133-S.B.S.
The Dole Queue In a serious attempt to downsize (reduce) the dole queue, The New National Green Lab ...
- 深度优先搜索 codevs 1064 虫食算
codevs 1064 虫食算 2004年NOIP全国联赛提高组 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 所 ...
- hdu-5521 Meeting(最短路)
题目链接: Meeting Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) ...
- 解决svn的working copy locked并且cleanup恢复不能的情况
产生这种情况大多是因为上次svn命令执行失败且被锁定了. 如果cleanup没有效果的话只好手动删除锁定文件. cd 到svn项目目录下,然后执行如下命令 del lock /q/s 就把锁删掉了.