using ComPDFKit.PDFDocument; using ComPDFKit.PDFPage; using Microsoft.Win32; using PDF_Office.Model; using PDF_Office.Model.Dialog.ToolsDialogs; using PDF_Office.Views.Dialog; using Prism.Commands; using Prism.Mvvm; using Prism.Services.Dialogs; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Imaging; namespace PDF_Office.ViewModels.Dialog.ToolsDialogs { class MergeDialogViewModel : BindableBase, IDialogAware { enum PageSizeType { kDefault = 0, A4 = 1, A3 = 2, Letter = 3, Legal = 4, Customized = 5, } #region 框架内容 public string Title => ""; public event Action RequestClose; public bool CanCloseDialog() { return true; } public void OnDialogClosed() { } public void OnDialogOpened(IDialogParameters parameters) { } #endregion #region 定义与初始化 public ObservableCollection MergeObjectlist { get; set; } public DelegateCommand CancelCommand { get; set; } public DelegateCommand MergeCommand { get; set; } public DelegateCommand AddFilesCommand { get; set; } public DelegateCommand ClearCommand { get; set; } public DelegateCommand SetPageSizeTypeCommand { get; set; } public IDialogService dialogs; private PageSizeType pageSizeType = PageSizeType.kDefault; private string inputWidth; public string InputWidth { get { return inputWidth; } set { SetProperty(ref inputWidth, value); } } private string inputHeight; public string InputHeight { get { return inputHeight; } set { SetProperty(ref inputHeight, value); } } public MergeDialogViewModel(IDialogService dialogService) { dialogs = dialogService; MergeObjectlist = new ObservableCollection(); CancelCommand = new DelegateCommand(Cancel); AddFilesCommand = new DelegateCommand(ButtonAddFiles); MergeCommand = new DelegateCommand(Merge); ClearCommand = new DelegateCommand(Clear); SetPageSizeTypeCommand = new DelegateCommand(SetPageSizeType); } #endregion #region 私有方法 private void Cancel() { RequestClose.Invoke(new DialogResult(ButtonResult.Cancel)); } public void ButtonAddFiles() { AddFiles(OpenFile()); } private string[] OpenFile() { OpenFileDialog openFile = new OpenFileDialog(); openFile.Multiselect = true; openFile.Filter = "Files(*pdf;*.bmp;*.gif;*.jpeg;*.jpg;*.png;*.tiff)|*.pdf;*.bmp;*.gif;*.jpeg;*.jpg;*.png;*.tiff|" + "(*.pdf)|*.pdf|" + "(*.bmp)|*.bmp|" + "(*.gif)|*.gif|" + "(*.jpeg)|*.jpeg|" + "(*.jpg)|*.jpg|" + "(*.png)|*.png|" + "(*.tiff)|*.tiff"; if (openFile.ShowDialog() == false) { return null; } return openFile.FileNames; } private string GetFileSize(string path) { System.IO.FileInfo fileInfo = null; try { fileInfo = new System.IO.FileInfo(path); } catch { return "0KB"; } if (fileInfo != null && fileInfo.Exists) { var size = Math.Round(fileInfo.Length / 1024.0, 0); if (size > 1024) { var sizeDouble = Math.Round(size / 1024.0, 2); if (sizeDouble > 1024) { sizeDouble = Math.Round(sizeDouble / 1024.0, 2); return sizeDouble + "G"; } else return sizeDouble + "M"; } else { return (int)System.Math.Ceiling(size) + "KB"; } } else { return "0KB"; } } private void Merge() { bool result = true; CPDFDocument SaveDoc = CPDFDocument.CreateDocument(); for (int i = 0; i < MergeObjectlist.Count; i++) { //图片 if (Path.GetExtension(MergeObjectlist[i].FilePath).Trim().ToLower() != "pdf") { BitmapSource frame = MergeObjectlist[i].DocThumbnail; byte[] imageData = new byte[frame.PixelWidth * frame.PixelHeight * 4]; if (frame.Format != PixelFormats.Bgra32) { FormatConvertedBitmap covert = new FormatConvertedBitmap(frame, PixelFormats.Bgra32, frame.Palette, 0); covert.CopyPixels(imageData, frame.PixelWidth * 4, 0); } else { frame.CopyPixels(imageData, frame.PixelWidth * 4, 0); } frame.CopyPixels(imageData, frame.PixelWidth * 4, 0); result = SaveDoc.InsertPage(0, frame.PixelWidth, frame.PixelHeight, imageData, CPDFDocumentImageMode.CPDFDocumentImageModeScaleToFill); if (!result) { SaveDoc.Release(); return; } continue; } else { CPDFDocument tempDoc = CPDFDocument.InitWithFilePath(MergeObjectlist[i].FilePath); if (!string.IsNullOrEmpty(MergeObjectlist[i].Password)) { tempDoc.UnlockWithPassword(MergeObjectlist[i].Password); } result = SaveDoc.ImportPages(tempDoc, MergeObjectlist[i].SetPageRange); if (!result) { SaveDoc.Release(); tempDoc.Release(); return; } tempDoc.Release(); } } string path = App.CachePath.MergeFilePath; string name = Guid.NewGuid().ToString(); if (!string.IsNullOrEmpty(path)) { path = System.IO.Path.Combine(path, name); } else { return; } System.Windows.Rect rect = new System.Windows.Rect(); switch (pageSizeType) { case PageSizeType.kDefault: break; case PageSizeType.A4: break; case PageSizeType.A3: break; case PageSizeType.Letter: break; case PageSizeType.Legal: break; case PageSizeType.Customized: if (!string.IsNullOrEmpty(InputWidth) && !string.IsNullOrEmpty(InputHeight)) { rect.Width = Convert.ToInt32(InputWidth); rect.Height = Convert.ToInt32(InputHeight); } else { rect.Width = 595; rect.Height = 841; } break; default: break; } if (rect.Width > 0 && rect.Height > 0) { //裁剪 for (int i = 0; i < SaveDoc.PageCount; i++) { CPDFPage page = SaveDoc.PageAtIndex(i); page.CropPage(CPDFDisplayBox.MediaBox, rect); } } bool saveResult = SaveDoc.WriteToFilePath(path); SaveDoc.Release(); DialogParameters valuePairs = new DialogParameters(); valuePairs.Add(ParameterNames.FilePath, path); RequestClose.Invoke(new DialogResult(ButtonResult.OK, valuePairs)); } private void Clear() { MergeObjectlist.Clear(); } private void SetPageSizeType(object button) { if (button is RadioButton) { pageSizeType = (PageSizeType)Convert.ToInt32((button as RadioButton).Tag); } } #endregion #region 公开方法 public void DeleteItem(MergeObject merge) { MergeObjectlist.Remove(merge); } public void MoveMerge(MergeObject targetNode, MergeObject soureNode) { int targetindex = MergeObjectlist.IndexOf(targetNode); MergeObjectlist.Remove(soureNode); if (targetNode.IsForward) { if (targetindex + 1 < MergeObjectlist.Count) { MergeObjectlist.Insert(targetindex + 1, soureNode); } else { MergeObjectlist.Add(soureNode); } } else { MergeObjectlist.Insert(targetindex, soureNode); } } public void AddFiles(string[] FilePath) { if (FilePath == null) { return; } bool result = true; for (int i = 0; i < FilePath.Length; i++) { MergeObject mergeObject = new MergeObject(); mergeObject.FilePath = FilePath[i]; //通过路径判断文件是否已添加 bool IsExists = false; for (int j = 0; j < MergeObjectlist.Count; j++) { if (MergeObjectlist[j].FilePath == mergeObject.FilePath) { IsExists = true; } } if (IsExists) { continue; } string FileType = Path.GetExtension(mergeObject.FilePath).Trim().ToLower(); if (FileType != ".pdf") { if (!Properties.Resources.imageex.Contains(FileType)) { //图片格式不支持 continue; }; mergeObject.DocName = Path.GetFileName(mergeObject.FilePath); mergeObject.DocPageCount = 1 + "页"; mergeObject.SDKPageCount = 1; mergeObject.DocSize = GetFileSize(mergeObject.FilePath); mergeObject.DocThumbnail = new BitmapImage(new Uri(mergeObject.FilePath)); ; } else { CPDFDocument doc = CPDFDocument.InitWithFilePath(mergeObject.FilePath); if (doc.IsLocked) { DialogParameters value = new DialogParameters(); value.Add(ParameterNames.PDFDocument, doc); dialogs.ShowDialog(DialogNames.VerifyPassWordDialog, value, e => { if (e.Result != ButtonResult.OK) { result = false; } else { mergeObject.Password = e.Parameters.GetValue(ParameterNames.PassWord); } }); if (!result) { doc.Release(); continue; } } mergeObject.DocName = doc.FileName; mergeObject.DocPageCount = doc.PageCount.ToString() + "页"; mergeObject.SDKPageCount = doc.PageCount; mergeObject.DocSize = GetFileSize(mergeObject.FilePath); //获取第一页缩略图 CPDFPage page = doc.PageAtIndex(0); Size size = doc.GetPageSize(0); byte[] bmpData = new byte[(int)(size.Width * size.Height * 4)]; WriteableBitmap WirteBitmap = new WriteableBitmap((int)size.Width, (int)size.Height, 96, 96, PixelFormats.Bgra32, null); page.RenderPageBitmap(0, 0, (int)size.Width, (int)size.Height, 0xFFFFFFFF, bmpData, 1); WirteBitmap.WritePixels(new Int32Rect(0, 0, (int)size.Width, (int)size.Height), bmpData, WirteBitmap.BackBufferStride, 0); WirteBitmap.Freeze(); mergeObject.DocThumbnail = WirteBitmap; doc.Release(); } MergeObjectlist.Add(mergeObject); } } #endregion } }