using ComDocumentAIKit; using ComPDFKit.PDFDocument; using ComPDFKit.PDFPage; using ComPDFKitViewer; using ComPDFKitViewer.PdfViewer; using PDF_Office.EventAggregators; using PDF_Office.Helper; using PDF_Office.Model; using Prism.Events; using Prism.Mvvm; using Prism.Regions; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Threading; namespace PDF_Office.ViewModels.Scan { class ScanViwerViewModel : BindableBase, INavigationAware { private CPDFViewer PDFViewer; private WriteableBitmap bgImage; public WriteableBitmap BgImage { get { return bgImage; } set { SetProperty(ref bgImage, value); } } private List> textRectList; public List> TextRectList { get { return textRectList; } set { SetProperty(ref textRectList, value); } } private bool isEnhanced; public bool IsEnhanced { get { return isEnhanced; } set { SetProperty(ref isEnhanced, value); } } /// /// 增强扫描结果路径 /// public List EnhancedFilePathList; /// /// OCR结果路径 /// private Dictionary>> cacahe; public bool IsNavigationTarget(NavigationContext navigationContext) { return true; } public void OnNavigatedFrom(NavigationContext navigationContext) { return; } public void OnNavigatedTo(NavigationContext navigationContext) { navigationContext.Parameters.TryGetValue(ParameterNames.PDFViewer, out PDFViewer); if (PDFViewer == null) { return; } else { PDFViewer.InfoChanged += PDFViewer_InfoChanged; PDFViewer.ChangeViewMode(ViewMode.Single); //第一次进入获取当前预览显示内容 CPDFPage pdfPage = PDFViewer.Document.PageAtIndex(PDFViewer.CurrentIndex); float zoom = (float)(DpiHelpers.Dpi / 72D); int renderWidth = (int)(pdfPage.PageSize.Width * zoom); int renderHeight = (int)(pdfPage.PageSize.Height * zoom); byte[] renderData = new byte[renderWidth * renderHeight * 4]; pdfPage.RenderPageBitmapWithMatrix(zoom, new Rect(0, 0, renderWidth, renderHeight), 0xFFFFFFFF, renderData, 0); BgImage = new WriteableBitmap(renderWidth, renderHeight, DpiHelpers.Dpi, DpiHelpers.Dpi, PixelFormats.Bgra32, null); BgImage.WritePixels(new Int32Rect(0, 0, renderWidth, renderHeight), renderData, BgImage.BackBufferStride, 0); } } private void PDFViewer_InfoChanged(object sender, KeyValuePair e) { if (e.Key == "PageNum") { RenderData renderData = e.Value as RenderData; if (renderData != null) { if (IsEnhanced) { BitmapImage image = new BitmapImage(new Uri(EnhancedFilePathList[PDFViewer.CurrentIndex])); BgImage = new WriteableBitmap(image); } else { CPDFPage pdfPage = PDFViewer.Document.PageAtIndex(renderData.PageIndex - 1); float zoom = (float)(DpiHelpers.Dpi / 72D); int renderWidth = (int)(pdfPage.PageSize.Width * zoom); int renderHeight = (int)(pdfPage.PageSize.Height * zoom); byte[] Data = new byte[renderWidth * renderHeight * 4]; pdfPage.RenderPageBitmapWithMatrix(zoom, new Rect(0, 0, renderWidth, renderHeight), 0xFFFFFFFF, Data, 0); BgImage = new WriteableBitmap(renderWidth, renderHeight, DpiHelpers.Dpi, DpiHelpers.Dpi, PixelFormats.Bgra32, null); BgImage.WritePixels(new Int32Rect(0, 0, renderWidth, renderHeight), Data, BgImage.BackBufferStride, 0); } if (cacahe.Count > 0) { if (cacahe.ContainsKey(renderData.PageIndex - 1)) { TextRectList = cacahe[renderData.PageIndex - 1]; } else { TextRectList = null; } } } } } public ScanViwerViewModel(IEventAggregator eventAggregator) { EnhancedFilePathList = new List(); eventAggregator.GetEvent().Subscribe(ChangeScanMode, e => e.Unicode == App.mainWindowViewModel.SelectedItem.Unicode); cacahe = new Dictionary>>(); } /// /// 根据Vm事件通知处理OCR与区域识别或者增强扫描事件 /// /// private void ChangeScanMode(ScanEventArgs e) { switch (e.Mode) { case ScanMode.Unknown: break; case ScanMode.Enhanced: EnhancedProcess(e); IsEnhanced = true; break; case ScanMode.OCR: if (IsEnhanced) { EnhancedOCRProcess(e); } else { OCRProcess(e); } break; case ScanMode.Area: break; default: break; } } private void EnhancedProcess(ScanEventArgs args) { CPDFDocument CurrentDoc = PDFViewer.Document; string path = App.CachePath.MergeFilePath; string name = Guid.NewGuid().ToString(); path = Path.Combine(path, name); string EnhancePath = Path.Combine(path, "Enhance"); Directory.CreateDirectory(path); Directory.CreateDirectory(EnhancePath); Task.Run(() => { CIMEngine imEngine = new CIMEngine(App.modelFolderPath); CErrorCode error = imEngine.SetModel(); for (int i = 0; i < CurrentDoc.PageCount; i++) { string pageImagePath = Path.Combine(path, i.ToString()); string pageEnhancePath = Path.Combine(EnhancePath, i.ToString() + ".png"); try { CPDFPage pdfPage = CurrentDoc.PageAtIndex(i); float zoom = (float)(DpiHelpers.Dpi / 72D); int renderWidth = (int)(pdfPage.PageSize.Width * zoom); int renderHeight = (int)(pdfPage.PageSize.Height * zoom); byte[] renderData = new byte[renderWidth * renderHeight * 4]; pdfPage.RenderPageBitmapWithMatrix(zoom, new Rect(0, 0, renderWidth, renderHeight), 0xFFFFFFFF, renderData, 0); WriteableBitmap bitmap = new WriteableBitmap(renderWidth, renderHeight, DpiHelpers.Dpi, DpiHelpers.Dpi, PixelFormats.Bgra32, null); bitmap.WritePixels(new Int32Rect(0, 0, renderWidth, renderHeight), renderData, bitmap.BackBufferStride, 0); BitmapEncoder encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(bitmap)); using (FileStream imageStream = File.Create(pageImagePath)) { encoder.Save(imageStream); imageStream.Flush(); } //File.Create(pageEnhancePath); error = imEngine.Process(pageImagePath, pageEnhancePath); EnhancedFilePathList.Add(pageEnhancePath); } catch { } } Application.Current.Dispatcher.Invoke(() => { BitmapImage image = new BitmapImage(new Uri(EnhancedFilePathList[PDFViewer.CurrentIndex])); BgImage = new WriteableBitmap(image); }); imEngine.Release(); }); } /// /// 使用当前文档OCR /// /// private void OCRProcess(ScanEventArgs args) { Task.Run(() => { COCREngine imEngine = new COCREngine(App.modelFolderPath); //CIMEngine imEngine = new CIMEngine(App.modelFolderPath); string path = App.CachePath.MergeFilePath; string name = Guid.NewGuid().ToString(); path = Path.Combine(path, name); Directory.CreateDirectory(path); CPDFDocument CurrentDoc = PDFViewer.Document; CErrorCode error = imEngine.SetModel((COCRLanguage)args.ScanLanguage); cacahe.Clear(); for (int i = 0; i < args.PageRange.Count; i++) { string pageImagePath = Path.Combine(path, args.PageRange[i].ToString()); CPDFPage pdfPage = CurrentDoc.PageAtIndex(args.PageRange[i]); float zoom = (float)(DpiHelpers.Dpi / 72D); int renderWidth = (int)(pdfPage.PageSize.Width * zoom); int renderHeight = (int)(pdfPage.PageSize.Height * zoom); byte[] renderData = new byte[renderWidth * renderHeight * 4]; pdfPage.RenderPageBitmapWithMatrix(zoom, new Rect(0, 0, renderWidth, renderHeight), 0xFFFFFFFF, renderData, 0); WriteableBitmap bitmap = new WriteableBitmap(renderWidth, renderHeight, DpiHelpers.Dpi, DpiHelpers.Dpi, PixelFormats.Bgra32, null); bitmap.WritePixels(new Int32Rect(0, 0, renderWidth, renderHeight), renderData, bitmap.BackBufferStride, 0); BitmapEncoder encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(bitmap)); using (FileStream imageStream = File.Create(pageImagePath)) { encoder.Save(imageStream); imageStream.Flush(); } error = imEngine.Process(pageImagePath); if (imEngine.OCRResultList == null) return; List> RectList = new List>(); foreach (COCRResult ocrResult in imEngine.OCRResultList) { List rectPoints = new List(); for (int j = 0; j < ocrResult.position.Length; j += 2) { rectPoints.Add(new Point(ocrResult.position[j], ocrResult.position[j + 1])); } int left = (int)rectPoints.AsEnumerable().Min(x => x.X); int right = (int)rectPoints.AsEnumerable().Max(x => x.X); int top = (int)rectPoints.AsEnumerable().Min(x => x.Y); int bottom = (int)rectPoints.AsEnumerable().Max(x => x.Y); RectList.Add(new KeyValuePair(new Rect(left, top, right - left, bottom - top), ocrResult.text)); } cacahe.Add(args.PageRange[i], RectList); } if (cacahe.Count > 0) { if (cacahe.ContainsKey(PDFViewer.CurrentIndex)) { TextRectList = cacahe[PDFViewer.CurrentIndex]; } else { TextRectList = null; } } imEngine.Release(); }); } /// /// 使用增强扫描结果进行OCR /// /// private void EnhancedOCRProcess(ScanEventArgs args) { Task.Run(() => { COCREngine imEngine = new COCREngine(App.modelFolderPath); CErrorCode error = imEngine.SetModel((COCRLanguage)args.ScanLanguage); cacahe.Clear(); for (int i = 0; i < args.PageRange.Count; i++) { error = imEngine.Process(EnhancedFilePathList[args.PageRange[i]]); if (imEngine.OCRResultList == null) return; List> RectList = new List>(); foreach (COCRResult ocrResult in imEngine.OCRResultList) { List rectPoints = new List(); for (int j = 0; j < ocrResult.position.Length; j += 2) { rectPoints.Add(new Point(ocrResult.position[j], ocrResult.position[j + 1])); } int left = (int)rectPoints.AsEnumerable().Min(x => x.X); int right = (int)rectPoints.AsEnumerable().Max(x => x.X); int top = (int)rectPoints.AsEnumerable().Min(x => x.Y); int bottom = (int)rectPoints.AsEnumerable().Max(x => x.Y); RectList.Add(new KeyValuePair(new Rect(left, top, right - left, bottom - top), ocrResult.text)); } cacahe.Add(args.PageRange[i], RectList); } if (cacahe.Count > 0) { if (cacahe.ContainsKey(PDFViewer.CurrentIndex)) { TextRectList = cacahe[PDFViewer.CurrentIndex]; } else { TextRectList = null; } } imEngine.Release(); }); } } }