使用OneNote的COM组件,实现OCR功能。

 背景

       在业务系统开发的过程中,很多情况下会去识别图片中的相关信息,并且把信息录入到系统中。现在希望通过自动化的方式录入,就有了以下的工作。在对比了几个OCR软件在中文识别方面的准确率后,决定使用微软的OneNote开发相应的功能。

        准备工作

  1. 安装OneNote 2010;(注:在 Microsoft Office 2003 中的工具组件中有一个“ Microsoft Office Document Imaging”的组件包,之后的Office版本将这个功能集成到OneNote中了)
  2. 查询网上相关OneNote的资料,真是少得可怜,即使找到现有的代码也是各种坑。
  3. 在OneNote中的图片识别功能如下图,把图片放到一个tab中,右键图片就会出现红框所标注的功能,这个是我需要在程序中来调用的:
    使用OneNote的COM组件,实现OCR功能。_第1张图片 

     

           代码实现的逻辑

  1.  获取图片的Base64编码;
  2. 开启OneNote程序,在一个空的newfile.one中,生成一个新的page;
  3. 此时,新的page页中,会有一个固定格式的xml,把图片的Base64编码,更新到对应的节点上;
  4. 更新节点后,会自动调用OCR的功能,把识别出来的文字,放入到固定节点上;
  5. 从识别出来的文字节点上,取出相应的文字就可以了;
  6. 彻底销毁当前的页面(如果不是彻底的话,这个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 GetBase64(string strImgPath)
        {
            return GetBase64(new FileInfo(strImgPath));
        }


        ///
        /// 获取图片的Base64编码
        ///

        ///
        ///
        private Tuple 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("不支持的图片格式。", 0, 0);
                }
                byte[] buffer = ms.GetBuffer();
                return new Tuple(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 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(0, 1)), new XAttribute("originalPageNumber", "0"),
                                                     new XElement(ns + "Position",
                                                           new XAttribute("x", "0"), new XAttribute("y", "0"), new XAttribute("z", "0")),
                                                     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 / 1024 / 1024); // 文件大小 单位M
                System.Threading.Thread.Sleep(waitTime * (fileSize > 1 ? fileSize : 1)); // 小于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格式
                       
                           
                           
                            Base64


                            //以下标签由Onenote 2010自动生成,不要在程序中处理,目标是获取OCRText中的内容。
                           
                           
                               
                           

                           
                           
                           
                           
                           
                            ................
                       

                    */


                    /*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.
                       
                         
                             
                         

                       

                    */

     

        目前是桌面应用程序是实现了相关功能。预期期望是:任何一个系统通过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 2010;(注:在 Microsoft Office 2003 中的工具组件中有一个“ M

      程序效果图如下:识别效果还不错,剩下的就是根据所需要的信息,进行正则表达式的匹配就可以了。

使用OneNote的COM组件,实现OCR功能。_第2张图片

 

转载自:http://www.cnblogs.com/BenAndWang/p/5826634.html

你可能感兴趣的:(小功能,OCR,很有用的东东)