zoukankan      html  css  js  c++  java
  • Onenote实现OCR识别图片

    OCR识别推荐两个软件:

    1.       Tesseract:一个开源的,由谷歌维护的OCR软件。

    2.       Onenote:微软Office附带或者可以自己独立安装。

    3.       ONOM:别人封装的onenote api接口

    这次讲Onenote实现的OCR识别。github地址:https://github.com/everywan/Extraction.OCR

    注:2010版及其以后版本OCR实现方式类似:office将其转换为特定xm格式,然后提取想要的节点就ok了;onenote2007识别比较简单:通过MODI API接口直接之别。

    我这里是实现了 office2007office2010ocr识别函数。

    源程序下载:坚果云连接.net4.5vs2017RC。本机环境:windows10

     

        

      1 public class ExtractionOCR
      2     {
      3         #region
      4         private static readonly ExtractionOCR instance = new ExtractionOCR();
      5         public static ExtractionOCR Instance { get { return instance; } }
      6         public static string section_path { getset; }
      7         public static int waitTime = 3 * 1000;
      8         #endregion
      9         /// <summary>
     10         /// office2007 MODI组件OCR识别
     11         /// </summary>
     12         /// <param name="imgPath"></param>
     13         /// <returns></returns>
     14         public string Ocr_2007(string imgPath)
     15         {
     16             try
     17             {
     18                 var imgType = imgPath.Substring(imgPath.Length - 3);
     19                 var data = File.ReadAllBytes(imgPath);
     20                 string imgInfo = "";
     21                 int i = 0;
     22                 var localimgFile = AppDomain.CurrentDomain.BaseDirectory + @"" + Guid.NewGuid().ToString() + "." + imgType;
     23                 while (!imgInfo.Equals("转换成功") && i < 3)
     24                 {
     25                     ++i;
     26                     imgInfo = this.GetBase64(data, imgType, localimgFile);
     27                 }
     28                 MODI.Document doc = new MODI.Document();
     29                 doc.Create(localimgFile);
     30                 MODI.Image image;
     31                 MODI.Layout layout;
     32                 doc.OCR(MODI.MiLANGUAGES.miLANG_CHINESE_SIMPLIFIED, truetrue);
     33                 StringBuilder sb = new StringBuilder();
     34                 image = (MODI.Image)doc.Images[0];
     35                 layout = image.Layout;
     36                 sb.Append(layout.Text);
     37                 doc = null;
     38                 var localFilePath = AppDomain.CurrentDomain.BaseDirectory + @"" + Guid.NewGuid().ToString() + ".txt";
     39                 File.WriteAllText(localFilePath, sb.ToString());
     40                 Console.WriteLine(sb.ToString());
     41                 return localFilePath;
     42             }
     43             catch (Exception e)
     44             {
     45                 File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + @"log.txt", e.ToString());
     46                 return "";
     47             }
     48             finally
     49             {
     50                 GC.Collect();
     51             }
     52         }
     53         /// <summary>
     54         /// onenote 2010,注意需要先在onenote中创建笔记本,并且将至转换为onenote2007格式
     55         /// 推荐使用onenote2016(个人版即可),API与2010类似,(去掉XMLSchema.xs2007参数即可)其他可参考API参数命名。
     56         /// 注意1:一定要将dll属性中的“嵌入互操作类型”属性关闭
     57         /// </summary>
     58         /// <param name="imgPath"></param>
     59         /// <returns></returns>
     60         public string Ocr_2010(string imgPath)
     61         {
     62             try
     63             {
     64                 #region 确定section_path存在
     65                 section_path = @"C:UserszhenshengDesktop打杂ocrocr.one";
     66                 if (string.IsNullOrEmpty(section_path))
     67                 {
     68                     Console.WriteLine("请先建立笔记本");
     69                     File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + @"log.txt""需要先在onenote中创建笔记本,并且将至转换为onenote2007格式,且将.one文件得路径赋值给section_path");
     70                     return "";
     71                 }
     72                 #endregion
     73                 #region 准备数据
     74                 //后缀
     75                 var imgType = Path.GetExtension(imgPath);
     76                 imgPath = imgPath.Replace(".""");
     77                 var data = File.ReadAllBytes(imgPath);
     78                 //根据大小确定重试次数
     79                 int fileSize = Convert.ToInt32(data.Length / 1024 / 1024); // 文件大小 单位M
     80                 string guid = Guid.NewGuid().ToString();
     81                 string pageID = "{" + guid + "}{1}{B0}";  // 格式 {guid}{tab}{??}
     82                 string pageXml;
     83                 XNamespace ns;
     84                 var onenoteApp = new Microsoft.Office.Interop.OneNote.Application();  //onenote提供的API
     85                 if (onenoteApp == null)
     86                 {
     87                     File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + @"log.txt""Microsoft.Office.Interop.OneNote.Application()创建失败");
     88                     return "";
     89                 }
     90                 //重试使用
     91                 XmlNode xmlNode;
     92                 int retry = 0;
     93                 #endregion
     94                 do
     95                 {
     96                     #region 创建页面并返回pageID
     97                     string sectionID;
     98                     onenoteApp.OpenHierarchy(section_path, nullout sectionID, CreateFileType.cftSection);
     99                     onenoteApp.CreateNewPage(sectionID, out pageID);
    100                     #endregion
    101                     #region 获取onenote页面xml结构格式
    102                     string notebookXml;
    103                     onenoteApp.GetHierarchy(null, HierarchyScope.hsPages, out notebookXml, XMLSchema.xs2007);
    104                     var doc = XDocument.Parse(notebookXml);
    105                     ns = doc.Root.Name.Namespace;
    106                     #endregion
    107                     #region 将图片插入页面
    108                     Tuple<stringintint> imgInfo = this.GetBase64(data, imgType);
    109                     var page = new XDocument(new XElement(ns + "Page",
    110                                                     new XElement(ns + "Outline",
    111                                                     new XElement(ns + "OEChildren",
    112                                                         new XElement(ns + "OE",
    113                                                         new XElement(ns + "Image",
    114                                                             new XAttribute("format", imgType), new XAttribute("originalPageNumber""0"),
    115                                                             new XElement(ns + "Position",
    116                                                                 new XAttribute("x""0"), new XAttribute("y""0"), new XAttribute("z""0")),
    117                                                             new XElement(ns + "Size",
    118                                                                 new XAttribute("width", imgInfo.Item2), new XAttribute("height", imgInfo.Item3)),
    119                                                             new XElement(ns + "Data", imgInfo.Item1)))))));
    120                     page.Root.SetAttributeValue("ID", pageID);
    121                     onenoteApp.UpdatePageContent(page.ToString(), DateTime.MinValue, XMLSchema.xs2007);
    122                     #endregion
    123                     #region 通过轮询访问获取OCR识别的结果,轮询超时次数为6次
    124                     int count = 0;
    125                     do
    126                     {
    127                         System.Threading.Thread.Sleep(waitTime * (fileSize > 1 ? fileSize : 1)); // 小于1M的都默认1M
    128                         onenoteApp.GetPageContent(pageID, out pageXml, PageInfo.piBinaryData, XMLSchema.xs2007);
    129                     }
    130                     while (pageXml == "" && count++ < 6);
    131                     #endregion
    132                     #region 删除页面
    133                     onenoteApp.DeleteHierarchy(pageID, DateTime.MinValue);
    134                     //onenoteApp = null;
    135                     #endregion
    136                     #region 从xml中提取OCR识别后的文档信息,然后输出到string中
    137                     XmlDocument xmlDoc = new XmlDocument();
    138                     xmlDoc.LoadXml(pageXml);
    139                     XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
    140                     nsmgr.AddNamespace("one", ns.ToString());
    141                     xmlNode = xmlDoc.SelectSingleNode("//one:Image//one:OCRText", nsmgr);
    142                     #endregion
    143                 }
    144                 //如果OCR没有识别出信息,则重试三次(个人测试2010失败率为0.2~0.3)
    145                 while (xmlNode == null && retry++ < 3);
    146                 if (xmlNode == null)
    147                 {
    148                     File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + @"log.txt""OCR没有识别出值");
    149                     return "";
    150                 }
    151                 var localFilePath = AppDomain.CurrentDomain.BaseDirectory + @"" + Guid.NewGuid().ToString() + ".txt";
    152                 File.WriteAllText(localFilePath, xmlNode.InnerText.ToString());
    153                 Console.WriteLine(xmlNode.InnerText.ToString());
    154                 return localFilePath;
    155             }
    156             catch (Exception e)
    157             {
    158                 File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + @"log.txt", e.ToString());
    159                 return "";
    160             }
    161         }
    162         private string GetBase64(byte[] data, string imgType, string filePath)
    163         {
    164             using (MemoryStream ms = new MemoryStream())
    165             {
    166                 MemoryStream ms1 = new MemoryStream(data);
    167                 Bitmap bp = (Bitmap)Image.FromStream(ms1);
    168                 switch (imgType.ToLower())
    169                 {
    170                     case "jpg":
    171                         bp.Save(ms, ImageFormat.Jpeg);
    172                         break;
    173                     case "jpeg":
    174                         bp.Save(ms, ImageFormat.Jpeg);
    175                         break;
    176                     case "gif":
    177                         bp.Save(ms, ImageFormat.Gif);
    178                         break;
    179                     case "bmp":
    180                         bp.Save(ms, ImageFormat.Bmp);
    181                         break;
    182                     case "tiff":
    183                         bp.Save(ms, ImageFormat.Tiff);
    184                         break;
    185                     case "png":
    186                         bp.Save(ms, ImageFormat.Png);
    187                         break;
    188                     case "emf":
    189                         bp.Save(ms, ImageFormat.Emf);
    190                         break;
    191                     default:
    192                         return "不支持的图片格式。";
    193                 }
    194                 byte[] buffer = ms.ToArray();
    195                 File.WriteAllBytes(filePath, buffer);
    196                 ms1.Close();
    197                 ms.Close();
    198                 return "转换成功";
    199                 //return new Tuple<string, int, int>(Convert.ToBase64String(buffer), bp.Width, bp.Height);
    200             }
    201         }
    202         private Tuple<stringintint> GetBase64(byte[] data, string imgType)
    203         {
    204             using (MemoryStream ms = new MemoryStream())
    205             {
    206                 MemoryStream ms1 = new MemoryStream(data);
    207                 Bitmap bp = (Bitmap)Image.FromStream(ms1);
    208                 switch (imgType.ToLower())
    209                 {
    210                     case "jpg":
    211                         bp.Save(ms, ImageFormat.Jpeg);
    212                         break;
    213                     case "jpeg":
    214                         bp.Save(ms, ImageFormat.Jpeg);
    215                         break;
    216                     case "gif":
    217                         bp.Save(ms, ImageFormat.Gif);
    218                         break;
    219                     case "bmp":
    220                         bp.Save(ms, ImageFormat.Bmp);
    221                         break;
    222                     case "tiff":
    223                         bp.Save(ms, ImageFormat.Tiff);
    224                         break;
    225                     case "png":
    226                         bp.Save(ms, ImageFormat.Png);
    227                         break;
    228                     case "emf":
    229                         bp.Save(ms, ImageFormat.Emf);
    230                         break;
    231                     default:
    232                         return new Tuple<stringintint>("不支持的图片格式。"00);
    233                 }
    234                 byte[] buffer = ms.ToArray();
    235                 ms1.Close();
    236                 ms.Close();
    237                 return new Tuple<stringintint>(Convert.ToBase64String(buffer), bp.Width, bp.Height);
    238             }
    239         }
    240     }
    View Code

     

    注意:

    1.       office2007需要安装office sp2补丁。

    2.       谨记 关闭onenote.dll的 嵌入互操作类型 关闭

    3.       如果是在服务器上使用office/onenote,需要开启 桌面体验 功能。

    4.       如果是在服务器上使用onenote 2007,需要注意的是该组件是32位的,也就是说直接调用这个接口的必须是32位程序。

    5.       如果是在服务器上使用onenote 2010,出现了(Retrieving the COM class factory for component with CLSID {D7FAC39E-7FF1-49AA-98CF-A1DDD316337E} failed due to the following error: 80080005 Server execution failed (Exception from HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE)))这个异常,请在调用此dll服务登陆身份修改为管理员账号,并且用此账号创建onenote笔记本,另外,本示例代码需要笔记本格式为onenote2007

    a.      

    6.       如果有其他异常,参阅微软文档: 错误代码

    参考:

    1.       onenote 2010 ocr实现

    2.       浅谈OCR之onenote 2010

    3.       Creating OneNote 2010 Extensions with the OneNote Object Model

    4.       64位进程调用32位dll的解决方法 / 程序64位化带来的问题和思考

    5.       ONOM :封装的onenote api

     

  • 相关阅读:
    android学习笔记22——Notification
    android学习笔记21——消息提示Toast
    android学习笔记20——ProgressDialog进度条对话框
    android学习笔记19——对话框(DatePickerDialog、TimePickerDialog)
    android学习笔记18——dpi、dp、sp、xp......
    android学习笔记17——对话框(PopupWindow)
    android学习笔记16——对话框
    android学习笔记15——Galley
    android学习笔记14——GridView、ImageSwitcher
    chapter09
  • 原文地址:https://www.cnblogs.com/jiangtu/p/6523507.html
Copyright © 2011-2022 走看看