ScanViwerViewModel.cs 17 KB

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