using ComPDFKitViewer.AnnotEvent; using ComPDFKitViewer.PdfViewer; using Microsoft.Win32; using PDF_Master.Model; using Prism.Commands; using Prism.Mvvm; using Prism.Regions; using Prism.Services.Dialogs; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Drawing; using System.Drawing.Imaging; using System.Globalization; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Ink; using System.Windows.Media; using System.Windows.Media.Imaging; namespace PDF_Master.ViewModels.PropertyPanel.AnnotPanel { class SignatureCreateDialogViewModel : BindableBase, IDialogAware { /// /// 非绘制时展示的画笔光标 /// private const double StrokeWidth = 3; private const double StrokeHigh = 3; public string Title => ""; private CPDFViewer PDFViewer; public event Action RequestClose; public DelegateCommand CancelCommand { get; set; } public DelegateCommand CreateCommnad { get; set; } public DelegateCommand UpdataDrawingStrokesCommnad { get; set; } public DelegateCommand CheckedCommnad { get; set; } public DelegateCommand OpenImageCommnad { get; set; } public DelegateCommand ClearTextCommnad { get; set; } public DelegateCommand ClearInkCanvasCommnad { get; set; } public ObservableCollection FontNameList { get; set; } public ObservableCollection ThicknessList { get; set; } private int fontNameIndex = 0; public int FontNameIndex { get { return fontNameIndex; } set { SetProperty(ref fontNameIndex, value); } } private int radioButtonIndex = 1; public int RadioButtonIndex { get { return radioButtonIndex; } set { SetProperty(ref radioButtonIndex, value); } } private int tabItemIndex; public int TabItemIndex { get { return tabItemIndex; } set { SetProperty(ref tabItemIndex, value); } } private string inputText = ""; public string InputText { get { return inputText; } set { SetProperty(ref inputText, value); } } private Visibility showTextButton = Visibility.Collapsed; public Visibility ShowTextButton { get { return showTextButton; } set { SetProperty(ref showTextButton, value); } } private Visibility showImageButton = Visibility.Visible; public Visibility ShowImageButton { get { return showImageButton; } set { SetProperty(ref showImageButton, value); } } private BitmapSource imagePreviewSource; public BitmapSource ImagePreviewSource { get { return imagePreviewSource; } set { SetProperty(ref imagePreviewSource, value); } } private bool issRemoveBackground; public bool IsRemoveBackground { get { return issRemoveBackground; } set { SetProperty(ref issRemoveBackground, value); if (issRemoveBackground) { if (IsNewFile) { removeBackgroundImagePreviewSource = ToBitmapImage(KnockOutGzf()); } ImagePreviewSource = removeBackgroundImagePreviewSource; } else { ImagePreviewSource = originalimagePreviewSource; } } } private DrawingAttributes drawingAttributes; public DrawingAttributes DrawingAttributeObject { get { return drawingAttributes; } set { SetProperty(ref drawingAttributes, value); } } private StrokeCollection strokes; public StrokeCollection StrokesObject { get { return strokes; } set { SetProperty(ref strokes, value); } } private bool isMouseDown = false; public bool IsMouseDown { get { return isMouseDown; } set { SetProperty(ref isMouseDown, value); } } private Visibility showPlanGrid = Visibility.Visible; public Visibility ShowPlanGrid { get { return showPlanGrid; } set { SetProperty(ref showPlanGrid, value); } } private int imageRadioButtonIndex = 1; public int ImageRadioButtonIndex { get { return imageRadioButtonIndex; } set { SetProperty(ref imageRadioButtonIndex, value); switch (imageRadioButtonIndex) { case 1: DrawingAttributeObject.Color = System.Windows.Media.Color.FromArgb(0xFF, 0x25, 0x26, 0x29); break; case 2: DrawingAttributeObject.Color = System.Windows.Media.Color.FromArgb(0xFF, 0xF3, 0x46, 0x5B); break; case 3: DrawingAttributeObject.Color = System.Windows.Media.Color.FromArgb(0xFF, 0x27, 0x3C, 0x62); break; case 4: DrawingAttributeObject.Color = System.Windows.Media.Color.FromArgb(0xFF, 0x94, 0x98, 0x9C); break; default: break; } if (ThicknessListIndex >= 0) { DrawingAttributeObject.Width = DrawingAttributeObject.Height = Convert.ToDouble(ThicknessList[ThicknessListIndex].Substring(0, 3)); UpDataToStrokesObject(); } } } private int thicknessListIndex = 1; public int ThicknessListIndex { get { return thicknessListIndex; } set { SetProperty(ref thicknessListIndex, value); if (thicknessListIndex >= 0) { DrawingAttributeObject.Width = DrawingAttributeObject.Height = Convert.ToDouble(ThicknessList[thicknessListIndex].Substring(0, 3)); UpDataToStrokesObject(); } } } public string SaveToPath { get; private set; } public string RemoveBackgroundSaveToPath { get; private set; } public string DrawingSaveToPath { get; private set; } /// /// 用于判断是否更换了文件,更换了文件则需要重新计算去背功能 /// private bool IsNewFile = false; //去背图片和原图的图片数据 private BitmapSource originalimagePreviewSource = null; private BitmapSource removeBackgroundImagePreviewSource = null; public SignatureCreateDialogViewModel() { DrawingAttributeObject = new DrawingAttributes(); StrokesObject = new StrokeCollection(); FontNameList = new ObservableCollection(); ThicknessList = new ObservableCollection() { "1.0pt", "2.0pt", "4.0pt", "6.0pt", "8.0pt" };//改了这里记得去改ThicknessListIndex的Set方法里面的取值 CancelCommand = new DelegateCommand(Cancel); CreateCommnad = new DelegateCommand(Create); UpdataDrawingStrokesCommnad = new DelegateCommand(UpdataDrawingStrokes); CheckedCommnad = new DelegateCommand(Checked); OpenImageCommnad = new DelegateCommand(OpenImage); ClearTextCommnad = new DelegateCommand(ClearText); ClearInkCanvasCommnad = new DelegateCommand(ClearInkCanvas); DrawingAttributeObject.Color = Colors.Black; DrawingAttributeObject.Width = StrokeWidth; DrawingAttributeObject.Height = StrokeHigh; WeakEventManager.AddHandler(StrokesObject, "StrokesChanged", StrokesObject_StrokesChanged); InitFontNameList(); } private void StrokesObject_StrokesChanged(object sender, StrokeCollectionChangedEventArgs e) { DrawingAttributeObject.Width = StrokeWidth; DrawingAttributeObject.Height = StrokeHigh; } private void InitFontNameList() { System.Drawing.Text.InstalledFontCollection objFont = new System.Drawing.Text.InstalledFontCollection(); foreach (var item in objFont.Families) { FontNameList.Add(item.Name); } } private void Checked(object index) { RadioButtonIndex = Convert.ToInt32(index); } public void UpDataImageRadioButtonIndex(int Index) { ImageRadioButtonIndex = Index; } public void UpDataRadioButtonIndex(int Index) { RadioButtonIndex = Index; } /// /// 更新画板所有内容状态 /// private void UpDataToStrokesObject() { foreach (var item in StrokesObject) { item.DrawingAttributes = DrawingAttributeObject.Clone(); } DrawingAttributeObject.Width = StrokeWidth; DrawingAttributeObject.Height = StrokeHigh; } private void ClearText() { InputText = ""; } private void OpenImage() { OpenFileDialog openFile = new OpenFileDialog(); openFile.Filter = "All Image Files(*.bmp;*.gif;*.jpeg;*.jpg;*.png;*.tiff)|*.bmp;*.gif;*.jpeg;*.jpg;*.png;*.tiff|(*.bmp)|*.bmp|" + "(*.gif)|*.gif|" + "(*.jpeg)|*.jpeg|" + "(*.jpg)|*.jpg|" + "(*.png)|*.png|" + "(*.tiff)|*.tiff"; if (openFile.ShowDialog() == false) { return; } string path = App.CachePath.CustomStampPath; string name = Guid.NewGuid().ToString(); if (!string.IsNullOrEmpty(path)) { //调整加载图片的方式,从Uri创建,路径中包含空格的图片无法成功添加 例如这个名称的图片:200200_6kb_jpg.jpg // 从文件中创建一个 Image 对象 Image img = Image.FromFile(openFile.FileName); // 将 Image 对象转换成 BitmapImage 对象 MemoryStream ms = new MemoryStream(); img.Save(ms, System.Drawing.Imaging.ImageFormat.Png); BitmapImage image = new BitmapImage(); image.BeginInit(); image.CacheOption = BitmapCacheOption.OnLoad; image.StreamSource = ms; image.EndInit(); double scale = Math.Min((double)600 / image.PixelWidth, (double)600 / image.PixelHeight); scale = Math.Min(scale, 1); BitmapEncoder encoder = new PngBitmapEncoder(); var targetBitmap = new TransformedBitmap(image, new ScaleTransform(scale, scale)); encoder.Frames.Add(BitmapFrame.Create(targetBitmap)); path = System.IO.Path.Combine(path, name); using (FileStream stream = new FileStream(path, FileMode.Create)) { encoder.Save(stream); } if (!string.IsNullOrEmpty(SaveToPath)) { App.CachePath.AddToDeleteFiles(SaveToPath); } IsNewFile = true; SaveToPath = path; ImagePreviewSource = originalimagePreviewSource = targetBitmap; ShowImageButton = Visibility.Collapsed; if (IsRemoveBackground) { ImagePreviewSource = removeBackgroundImagePreviewSource = ToBitmapImage(KnockOutGzf()); } } else { SaveToPath = ""; } } private void ClearInkCanvas() { StrokesObject.Clear(); } /// /// 去除白底 /// private Bitmap KnockOutGzf() { System.Drawing.Image image = System.Drawing.Image.FromFile(SaveToPath); Bitmap bitmapProxy = new Bitmap(image); image.Dispose(); for (int i = 0; i < bitmapProxy.Width; i++) { for (int j = 0; j < bitmapProxy.Height; j++) { System.Drawing.Color c = bitmapProxy.GetPixel(i, j); if (!(c.R < 240 || c.G < 240 || c.B < 240)) { bitmapProxy.SetPixel(i, j, System.Drawing.Color.Transparent); } } } return bitmapProxy; } /// /// 将 Bitmap 转化为 BitmapSource /// /// 要转换的 Bitmap /// 转换后的 BitmapImage private BitmapImage ToBitmapImage(System.Drawing.Bitmap bmp) { System.IO.MemoryStream ms = new System.IO.MemoryStream(); bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png); BitmapImage image = new BitmapImage(); image.BeginInit(); image.StreamSource = ms; image.CacheOption = BitmapCacheOption.OnLoad; image.EndInit(); //编码,缓存到本地 string path = App.CachePath.CustomStampPath; string name = Guid.NewGuid().ToString(); BitmapEncoder encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(image)); path = System.IO.Path.Combine(path, name); using (FileStream stream = new FileStream(path, FileMode.Create)) { encoder.Save(stream); } if (!string.IsNullOrEmpty(RemoveBackgroundSaveToPath)) { App.CachePath.AddToDeleteFiles(RemoveBackgroundSaveToPath); } RemoveBackgroundSaveToPath = path; IsNewFile = false; return image; } /// /// 把文字转换成Bitmap /// /// /// /// 用于输出的矩形,文字在这个矩形内显示,为空时自动计算 /// 字体颜色 /// 背景颜色 /// private Bitmap TextToBitmap(string text, string FontFamily, double size, Rectangle rect, System.Windows.Media.Brush fontcolor, System.Drawing.Color backColor) { FormattedText formatText = new FormattedText(text, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface(new System.Windows.Media.FontFamily(FontFamily), FontStyles.Normal, FontWeights.Normal, FontStretches.Normal), size, fontcolor, Helper.DpiHelpers.Dpi / 96F); DrawingVisual drawingVisual = new DrawingVisual(); DrawingContext dc = drawingVisual.RenderOpen(); dc.DrawText(formatText, new System.Windows.Point(2, 10)); dc.Close(); Rect x = drawingVisual.ContentBounds; Rect DrawRect = new Rect(0, 0, x.Width + (x.X / 2), x.Height + x.Y); RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap((int)((int)DrawRect.Width + (x.X / 2)), (int)((int)DrawRect.Height + x.Y), 96F, 96F, PixelFormats.Pbgra32); renderTargetBitmap.Render(drawingVisual); MemoryStream stream = new MemoryStream(); BitmapEncoder encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap)); encoder.Save(stream); Bitmap bitmap = new Bitmap(stream); return bitmap; } private void Cancel() { RequestClose.Invoke(new DialogResult(ButtonResult.Cancel)); } private void Create() { switch (TabItemIndex) { case 0: { if (string.IsNullOrEmpty(InputText)) { Cancel(); return; } System.Windows.Media.Brush fontcolor = new SolidColorBrush((System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#252629")); switch (RadioButtonIndex) { case 1: fontcolor = new SolidColorBrush((System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#252629")); break; case 2: fontcolor = new SolidColorBrush((System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#F3465B")); break; case 3: fontcolor = new SolidColorBrush((System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#273C62")); break; case 4: fontcolor = new SolidColorBrush((System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#94989C")); break; default: break; } Bitmap bmp = TextToBitmap(InputText, FontNameList[fontNameIndex], 50, Rectangle.Empty, fontcolor, System.Drawing.Color.Transparent); string guid = Guid.NewGuid().ToString(); string path = System.IO.Path.Combine(App.CachePath.SignatureStampPath, guid); bmp.Save(path, ImageFormat.Png); SaveToPath = path; } break; case 1: { var FreeHandpath = App.CachePath.SignatureFreeHandPath; string name = Guid.NewGuid().ToString(); FreeHandpath = System.IO.Path.Combine(FreeHandpath, name); using (System.IO.FileStream stream = new System.IO.FileStream(FreeHandpath, System.IO.FileMode.Create)) { StrokesObject.Save(stream); } StampAnnotArgs stampArgs = new StampAnnotArgs(); List> RawPointList = new List>(); for (int kk = 0; kk < StrokesObject.Count; kk++) { List p = new List(); RawPointList.Add(p); for (int gg = 0; gg < StrokesObject[kk].StylusPoints.Count; gg++) { var point = StrokesObject[kk].StylusPoints[gg].ToPoint(); if (point.X >= 0 && point.Y >= 0) RawPointList[kk].Add(point); } } DrawingSaveToPath = FreeHandpath; //根据当前选项创建预览图片 double inkThickness; if (ThicknessListIndex >= 0) { inkThickness = Convert.ToDouble(ThicknessList[ThicknessListIndex].Substring(0, 3)); } else { inkThickness = drawingAttributes.Width; } stampArgs.SetInkData(RawPointList, inkThickness, drawingAttributes.Color); var writeStamp = stampArgs.GetStampDrawing(); FreeHandpath = App.CachePath.SignatureStampPath; string thumbnailName = Guid.NewGuid().ToString(); FreeHandpath = System.IO.Path.Combine(FreeHandpath, thumbnailName); using (FileStream stream5 = new FileStream(FreeHandpath, FileMode.Create)) { PngBitmapEncoder encoder5 = new PngBitmapEncoder(); encoder5.Frames.Add(BitmapFrame.Create(writeStamp)); encoder5.Save(stream5); } SaveToPath = FreeHandpath; } break; case 2: break; default: break; } DialogParameters valuePairs = new DialogParameters(); valuePairs.Add(ParameterNames.DataModel, this); RequestClose.Invoke(new DialogResult(ButtonResult.OK, valuePairs)); } /// /// 绘制时使用的画笔 /// private void UpdataDrawingStrokes() { DrawingAttributeObject.Width = DrawingAttributeObject.Height = Convert.ToDouble(ThicknessList[thicknessListIndex].Substring(0, 3)); } public bool CanCloseDialog() { return true; } public void OnDialogClosed() { return; } public void OnDialogOpened(IDialogParameters parameters) { if (parameters != null) { PDFViewer = parameters.GetValue(ParameterNames.PDFViewer); if (PDFViewer != null) { } } return; } } }