ScanViwerViewModel.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. using ComDocumentAIKit;
  2. using ComPDFKit.PDFDocument;
  3. using ComPDFKit.PDFPage;
  4. using ComPDFKitViewer;
  5. using ComPDFKitViewer.PdfViewer;
  6. using PDF_Office.EventAggregators;
  7. using PDF_Office.Helper;
  8. using PDF_Office.Model;
  9. using Prism.Events;
  10. using Prism.Mvvm;
  11. using Prism.Regions;
  12. using System;
  13. using System.Collections.Generic;
  14. using System.IO;
  15. using System.Linq;
  16. using System.Text;
  17. using System.Threading.Tasks;
  18. using System.Windows;
  19. using System.Windows.Media;
  20. using System.Windows.Media.Imaging;
  21. using System.Windows.Threading;
  22. namespace PDF_Office.ViewModels.Scan
  23. {
  24. class ScanViwerViewModel : BindableBase, INavigationAware
  25. {
  26. private CPDFViewer PDFViewer;
  27. private WriteableBitmap bgImage;
  28. public WriteableBitmap BgImage
  29. {
  30. get { return bgImage; }
  31. set
  32. {
  33. SetProperty(ref bgImage, value);
  34. }
  35. }
  36. private List<KeyValuePair<Rect, string>> textRectList;
  37. public List<KeyValuePair<Rect, string>> TextRectList
  38. {
  39. get { return textRectList; }
  40. set
  41. {
  42. SetProperty(ref textRectList, value);
  43. }
  44. }
  45. private bool isEnhanced;
  46. public bool IsEnhanced
  47. {
  48. get { return isEnhanced; }
  49. set
  50. {
  51. SetProperty(ref isEnhanced, value);
  52. }
  53. }
  54. /// <summary>
  55. /// 增强扫描结果路径
  56. /// </summary>
  57. public List<string> EnhancedFilePathList;
  58. /// <summary>
  59. /// OCR结果路径
  60. /// </summary>
  61. private Dictionary<int, List<KeyValuePair<Rect, string>>> cacahe;
  62. public bool IsNavigationTarget(NavigationContext navigationContext)
  63. {
  64. return true;
  65. }
  66. public void OnNavigatedFrom(NavigationContext navigationContext)
  67. {
  68. return;
  69. }
  70. public void OnNavigatedTo(NavigationContext navigationContext)
  71. {
  72. navigationContext.Parameters.TryGetValue<CPDFViewer>(ParameterNames.PDFViewer, out PDFViewer);
  73. if (PDFViewer == null)
  74. {
  75. return;
  76. }
  77. else
  78. {
  79. PDFViewer.InfoChanged += PDFViewer_InfoChanged;
  80. PDFViewer.ChangeViewMode(ViewMode.Single);
  81. //第一次进入获取当前预览显示内容
  82. CPDFPage pdfPage = PDFViewer.Document.PageAtIndex(PDFViewer.CurrentIndex);
  83. float zoom = (float)(DpiHelpers.Dpi / 72D);
  84. int renderWidth = (int)(pdfPage.PageSize.Width * zoom);
  85. int renderHeight = (int)(pdfPage.PageSize.Height * zoom);
  86. byte[] renderData = new byte[renderWidth * renderHeight * 4];
  87. pdfPage.RenderPageBitmapWithMatrix(zoom, new Rect(0, 0, renderWidth, renderHeight), 0xFFFFFFFF, renderData, 0);
  88. BgImage = new WriteableBitmap(renderWidth, renderHeight, DpiHelpers.Dpi, DpiHelpers.Dpi, PixelFormats.Bgra32, null);
  89. BgImage.WritePixels(new Int32Rect(0, 0, renderWidth, renderHeight), renderData, BgImage.BackBufferStride, 0);
  90. }
  91. }
  92. private void PDFViewer_InfoChanged(object sender, KeyValuePair<string, object> e)
  93. {
  94. if (e.Key == "PageNum")
  95. {
  96. RenderData renderData = e.Value as RenderData;
  97. if (renderData != null)
  98. {
  99. if (IsEnhanced)
  100. {
  101. BitmapImage image = new BitmapImage(new Uri(EnhancedFilePathList[PDFViewer.CurrentIndex]));
  102. BgImage = new WriteableBitmap(image);
  103. }
  104. else
  105. {
  106. CPDFPage pdfPage = PDFViewer.Document.PageAtIndex(renderData.PageIndex - 1);
  107. float zoom = (float)(DpiHelpers.Dpi / 72D);
  108. int renderWidth = (int)(pdfPage.PageSize.Width * zoom);
  109. int renderHeight = (int)(pdfPage.PageSize.Height * zoom);
  110. byte[] Data = new byte[renderWidth * renderHeight * 4];
  111. pdfPage.RenderPageBitmapWithMatrix(zoom, new Rect(0, 0, renderWidth, renderHeight), 0xFFFFFFFF, Data, 0);
  112. BgImage = new WriteableBitmap(renderWidth, renderHeight, DpiHelpers.Dpi, DpiHelpers.Dpi, PixelFormats.Bgra32, null);
  113. BgImage.WritePixels(new Int32Rect(0, 0, renderWidth, renderHeight), Data, BgImage.BackBufferStride, 0);
  114. }
  115. if (cacahe.Count > 0)
  116. {
  117. if (cacahe.ContainsKey(renderData.PageIndex - 1))
  118. {
  119. TextRectList = cacahe[renderData.PageIndex - 1];
  120. }
  121. else
  122. {
  123. TextRectList = null;
  124. }
  125. }
  126. }
  127. }
  128. }
  129. public ScanViwerViewModel(IEventAggregator eventAggregator)
  130. {
  131. EnhancedFilePathList = new List<string>();
  132. eventAggregator.GetEvent<ScanEvent>().Subscribe(ChangeScanMode, e => e.Unicode == App.mainWindowViewModel.SelectedItem.Unicode);
  133. cacahe = new Dictionary<int, List<KeyValuePair<Rect, string>>>();
  134. }
  135. /// <summary>
  136. /// 根据Vm事件通知处理OCR与区域识别或者增强扫描事件
  137. /// </summary>
  138. /// <param name="e"></param>
  139. private void ChangeScanMode(ScanEventArgs e)
  140. {
  141. switch (e.Mode)
  142. {
  143. case ScanMode.Unknown:
  144. break;
  145. case ScanMode.Enhanced:
  146. EnhancedProcess(e);
  147. IsEnhanced = true;
  148. break;
  149. case ScanMode.OCR:
  150. if (IsEnhanced)
  151. {
  152. EnhancedOCRProcess(e);
  153. }
  154. else
  155. {
  156. OCRProcess(e);
  157. }
  158. break;
  159. case ScanMode.Area:
  160. break;
  161. default:
  162. break;
  163. }
  164. }
  165. private void EnhancedProcess(ScanEventArgs args)
  166. {
  167. CPDFDocument CurrentDoc = PDFViewer.Document;
  168. string path = App.CachePath.MergeFilePath;
  169. string name = Guid.NewGuid().ToString();
  170. path = Path.Combine(path, name);
  171. string EnhancePath = Path.Combine(path, "Enhance");
  172. Directory.CreateDirectory(path);
  173. Directory.CreateDirectory(EnhancePath);
  174. Task.Run(() =>
  175. {
  176. CIMEngine imEngine = new CIMEngine(App.modelFolderPath);
  177. CErrorCode error = imEngine.SetModel();
  178. for (int i = 0; i < CurrentDoc.PageCount; i++)
  179. {
  180. string pageImagePath = Path.Combine(path, i.ToString());
  181. string pageEnhancePath = Path.Combine(EnhancePath, i.ToString() + ".png");
  182. try
  183. {
  184. CPDFPage pdfPage = CurrentDoc.PageAtIndex(i);
  185. float zoom = (float)(DpiHelpers.Dpi / 72D);
  186. int renderWidth = (int)(pdfPage.PageSize.Width * zoom);
  187. int renderHeight = (int)(pdfPage.PageSize.Height * zoom);
  188. byte[] renderData = new byte[renderWidth * renderHeight * 4];
  189. pdfPage.RenderPageBitmapWithMatrix(zoom, new Rect(0, 0, renderWidth, renderHeight), 0xFFFFFFFF, renderData, 0);
  190. WriteableBitmap bitmap = new WriteableBitmap(renderWidth, renderHeight, DpiHelpers.Dpi, DpiHelpers.Dpi, PixelFormats.Bgra32, null);
  191. bitmap.WritePixels(new Int32Rect(0, 0, renderWidth, renderHeight), renderData, bitmap.BackBufferStride, 0);
  192. BitmapEncoder encoder = new PngBitmapEncoder();
  193. encoder.Frames.Add(BitmapFrame.Create(bitmap));
  194. using (FileStream imageStream = File.Create(pageImagePath))
  195. {
  196. encoder.Save(imageStream);
  197. imageStream.Flush();
  198. }
  199. //File.Create(pageEnhancePath);
  200. error = imEngine.Process(pageImagePath, pageEnhancePath);
  201. EnhancedFilePathList.Add(pageEnhancePath);
  202. }
  203. catch
  204. {
  205. }
  206. }
  207. Application.Current.Dispatcher.Invoke(() =>
  208. {
  209. BitmapImage image = new BitmapImage(new Uri(EnhancedFilePathList[PDFViewer.CurrentIndex]));
  210. BgImage = new WriteableBitmap(image);
  211. });
  212. imEngine.Release();
  213. });
  214. }
  215. /// <summary>
  216. /// 使用当前文档OCR
  217. /// </summary>
  218. /// <param name="args"></param>
  219. private void OCRProcess(ScanEventArgs args)
  220. {
  221. Task.Run(() =>
  222. {
  223. COCREngine imEngine = new COCREngine(App.modelFolderPath);
  224. //CIMEngine imEngine = new CIMEngine(App.modelFolderPath);
  225. string path = App.CachePath.MergeFilePath;
  226. string name = Guid.NewGuid().ToString();
  227. path = Path.Combine(path, name);
  228. Directory.CreateDirectory(path);
  229. CPDFDocument CurrentDoc = PDFViewer.Document;
  230. CErrorCode error = imEngine.SetModel((COCRLanguage)args.ScanLanguage);
  231. cacahe.Clear();
  232. for (int i = 0; i < args.PageRange.Count; i++)
  233. {
  234. string pageImagePath = Path.Combine(path, args.PageRange[i].ToString());
  235. CPDFPage pdfPage = CurrentDoc.PageAtIndex(args.PageRange[i]);
  236. float zoom = (float)(DpiHelpers.Dpi / 72D);
  237. int renderWidth = (int)(pdfPage.PageSize.Width * zoom);
  238. int renderHeight = (int)(pdfPage.PageSize.Height * zoom);
  239. byte[] renderData = new byte[renderWidth * renderHeight * 4];
  240. pdfPage.RenderPageBitmapWithMatrix(zoom, new Rect(0, 0, renderWidth, renderHeight), 0xFFFFFFFF, renderData, 0);
  241. WriteableBitmap bitmap = new WriteableBitmap(renderWidth, renderHeight, DpiHelpers.Dpi, DpiHelpers.Dpi, PixelFormats.Bgra32, null);
  242. bitmap.WritePixels(new Int32Rect(0, 0, renderWidth, renderHeight), renderData, bitmap.BackBufferStride, 0);
  243. BitmapEncoder encoder = new PngBitmapEncoder();
  244. encoder.Frames.Add(BitmapFrame.Create(bitmap));
  245. using (FileStream imageStream = File.Create(pageImagePath))
  246. {
  247. encoder.Save(imageStream);
  248. imageStream.Flush();
  249. }
  250. error = imEngine.Process(pageImagePath);
  251. if (imEngine.OCRResultList == null)
  252. return;
  253. List<KeyValuePair<Rect, string>> RectList = new List<KeyValuePair<Rect, string>>();
  254. foreach (COCRResult ocrResult in imEngine.OCRResultList)
  255. {
  256. List<Point> rectPoints = new List<Point>();
  257. for (int j = 0; j < ocrResult.position.Length; j += 2)
  258. {
  259. rectPoints.Add(new Point(ocrResult.position[j], ocrResult.position[j + 1]));
  260. }
  261. int left = (int)rectPoints.AsEnumerable().Min(x => x.X);
  262. int right = (int)rectPoints.AsEnumerable().Max(x => x.X);
  263. int top = (int)rectPoints.AsEnumerable().Min(x => x.Y);
  264. int bottom = (int)rectPoints.AsEnumerable().Max(x => x.Y);
  265. RectList.Add(new KeyValuePair<Rect, string>(new Rect(left, top, right - left, bottom - top), ocrResult.text));
  266. }
  267. cacahe.Add(args.PageRange[i], RectList);
  268. }
  269. if (cacahe.Count > 0)
  270. {
  271. if (cacahe.ContainsKey(PDFViewer.CurrentIndex))
  272. {
  273. TextRectList = cacahe[PDFViewer.CurrentIndex];
  274. }
  275. else
  276. {
  277. TextRectList = null;
  278. }
  279. }
  280. imEngine.Release();
  281. });
  282. }
  283. /// <summary>
  284. /// 使用增强扫描结果进行OCR
  285. /// </summary>
  286. /// <param name="args"></param>
  287. private void EnhancedOCRProcess(ScanEventArgs args)
  288. {
  289. Task.Run(() =>
  290. {
  291. COCREngine imEngine = new COCREngine(App.modelFolderPath);
  292. CErrorCode error = imEngine.SetModel((COCRLanguage)args.ScanLanguage);
  293. cacahe.Clear();
  294. for (int i = 0; i < args.PageRange.Count; i++)
  295. {
  296. error = imEngine.Process(EnhancedFilePathList[args.PageRange[i]]);
  297. if (imEngine.OCRResultList == null)
  298. return;
  299. List<KeyValuePair<Rect, string>> RectList = new List<KeyValuePair<Rect, string>>();
  300. foreach (COCRResult ocrResult in imEngine.OCRResultList)
  301. {
  302. List<Point> rectPoints = new List<Point>();
  303. for (int j = 0; j < ocrResult.position.Length; j += 2)
  304. {
  305. rectPoints.Add(new Point(ocrResult.position[j], ocrResult.position[j + 1]));
  306. }
  307. int left = (int)rectPoints.AsEnumerable().Min(x => x.X);
  308. int right = (int)rectPoints.AsEnumerable().Max(x => x.X);
  309. int top = (int)rectPoints.AsEnumerable().Min(x => x.Y);
  310. int bottom = (int)rectPoints.AsEnumerable().Max(x => x.Y);
  311. RectList.Add(new KeyValuePair<Rect, string>(new Rect(left, top, right - left, bottom - top), ocrResult.text));
  312. }
  313. cacahe.Add(args.PageRange[i], RectList);
  314. }
  315. if (cacahe.Count > 0)
  316. {
  317. if (cacahe.ContainsKey(PDFViewer.CurrentIndex))
  318. {
  319. TextRectList = cacahe[PDFViewer.CurrentIndex];
  320. }
  321. else
  322. {
  323. TextRectList = null;
  324. }
  325. }
  326. imEngine.Release();
  327. });
  328. }
  329. }
  330. }