|
| 1 | +using Syncfusion.Pdf; |
| 2 | +using Syncfusion.Pdf.Graphics; |
| 3 | +using Syncfusion.Pdf.Security; |
| 4 | +using Syncfusion.Windows.PdfViewer; |
| 5 | +using System; |
| 6 | +using System.Drawing; |
| 7 | +using System.IO; |
| 8 | +using System.Windows; |
| 9 | +using System.Windows.Controls; |
| 10 | +using System.Windows.Media; |
| 11 | +using Path = System.Windows.Shapes.Path; |
| 12 | +using Bitmap = System.Drawing.Bitmap; |
| 13 | + |
| 14 | +namespace WPF_Sample_FW |
| 15 | +{ |
| 16 | + /// <summary> |
| 17 | + /// Interaction logic for MainWindow.xaml |
| 18 | + /// </summary> |
| 19 | + public partial class MainWindow : Window |
| 20 | + { |
| 21 | + string filePath = "../../../Data/"; |
| 22 | + bool addSignature = false; |
| 23 | + public MainWindow() |
| 24 | + { |
| 25 | + InitializeComponent(); |
| 26 | + PDFViewer.Load(filePath + "Ink signature.pdf"); |
| 27 | + PDFViewer.Loaded += PDFViewer_Loaded; |
| 28 | + PDFViewer.ZoomMode = ZoomMode.FitPage; |
| 29 | + } |
| 30 | + |
| 31 | + private void PDFViewer_Loaded(object sender, RoutedEventArgs e) |
| 32 | + { |
| 33 | + // Find the default toolbar from the PDFViewer control template. |
| 34 | + DocumentToolbar toolbar = PDFViewer.Template.FindName("PART_Toolbar", PDFViewer) as DocumentToolbar; |
| 35 | + |
| 36 | + // Find the stack panel inside the toolbar where buttons are arranged. |
| 37 | + StackPanel stackPanel = (StackPanel)toolbar.Template.FindName("PART_ToolbarStack", toolbar); |
| 38 | + |
| 39 | + // Get the last stack panel in the toolbar stack (usually contains default buttons). |
| 40 | + StackPanel stack = stackPanel.Children[stackPanel.Children.Count - 1] as StackPanel; |
| 41 | + |
| 42 | + // Get the first button from the stack to copy its style and icon. |
| 43 | + Button button = stack.Children[0] as Button; |
| 44 | + Path oldStylePath = button.Content as Path; |
| 45 | + |
| 46 | + Button eSignButton = GetButton(oldStylePath, button); |
| 47 | + |
| 48 | + // Add the new eSign button to the toolbar stack. |
| 49 | + stackPanel.Children.Add(eSignButton); |
| 50 | + } |
| 51 | + |
| 52 | + private void eSignButton_Click(object sender, RoutedEventArgs e) |
| 53 | + { |
| 54 | + addSignature = true; |
| 55 | + } |
| 56 | + |
| 57 | + private Button GetButton(System.Windows.Shapes.Path oldPath, Button button) |
| 58 | + { |
| 59 | + // Create a new custom button for eSign functionality. |
| 60 | + Button eSignButton = new Button(); |
| 61 | + |
| 62 | + // Create a new Path object to use as the icon for the eSign button. |
| 63 | + Path path = new Path(); |
| 64 | + path.Data = System.Windows.Media.Geometry.Parse("M218.17 424.14c-2.95-5.92-8.09-6.52-10.17-6.52s-7.22.59-10.02 6.19l-7.67 15.34c-6.37 12.78-25.03 11.37-29.48-2.09L144 386.59l-10.61 31.88c-5.89 17.66-22.38 29.53-41 29.53H80c-8.84 0-16-7.16-16-16s7.16-16 16-16h12.39c4.83 0 9.11-3.08 10.64-7.66l18.19-54.64c3.3-9.81 12.44-16.41 22.78-16.41s19.48 6.59 22.77 16.41l13.88 41.64c19.75-16.19 54.06-9.7 66 14.16 1.89 3.78 5.49 5.95 9.36 6.26v-82.12l128-127.09V160H248c-13.2 0-24-10.8-24-24V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24v-40l-128-.11c-16.12-.31-30.58-9.28-37.83-23.75zM384 121.9c0-6.3-2.5-12.4-7-16.9L279.1 7c-4.5-4.5-10.6-7-17-7H256v128h128v-6.1zm-96 225.06V416h68.99l161.68-162.78-67.88-67.88L288 346.96zm280.54-179.63l-31.87-31.87c-9.94-9.94-26.07-9.94-36.01 0l-27.25 27.25 67.88 67.88 27.25-27.25c9.95-9.94 9.95-26.07 0-36.01z"); |
| 65 | + |
| 66 | + // Copy the fill color from the existing button's icon. |
| 67 | + path.Fill = oldPath.Fill; |
| 68 | + |
| 69 | + // Set the icon as the content of the new button. |
| 70 | + eSignButton.Content = path; |
| 71 | + |
| 72 | + // Match the icon's size and layout to the original button. |
| 73 | + path.Stretch = Stretch.Uniform; |
| 74 | + path.Height = oldPath.Height; |
| 75 | + path.Width = oldPath.Width; |
| 76 | + |
| 77 | + // Match the button's background and layout properties to the original button. |
| 78 | + eSignButton.Height = button.Height; |
| 79 | + eSignButton.Width = button.Width; |
| 80 | + eSignButton.Margin = button.Margin; |
| 81 | + eSignButton.Style = button.Style; |
| 82 | + // Attach the click event handler for eSign functionality. |
| 83 | + eSignButton.Click += eSignButton_Click; |
| 84 | + |
| 85 | + return eSignButton; |
| 86 | + } |
| 87 | + |
| 88 | + private void PDFViewer_PageClicked(object sender, PageClickedEventArgs args) |
| 89 | + { |
| 90 | + if (addSignature) |
| 91 | + { |
| 92 | + int pageIndex = PDFViewer.CurrentPageIndex - 1; |
| 93 | + CreateSignatureImage(); |
| 94 | + |
| 95 | + //Gets the first page of the document |
| 96 | + PdfLoadedPage page = PDFViewer.LoadedDocument.Pages[pageIndex] as PdfLoadedPage; |
| 97 | + |
| 98 | + //Retrieve the clicked client area position |
| 99 | + System.Windows.Point clientPoint = args.Position; |
| 100 | + |
| 101 | + // Convert client point to page point, which accounts for zoom mode. |
| 102 | + System.Windows.Point pagePoint = PDFViewer.ConvertClientPointToPagePoint(clientPoint, pageIndex + 1); |
| 103 | + double x = pagePoint.X; |
| 104 | + double y = pagePoint.Y; |
| 105 | + |
| 106 | + //Creates a certificate instance from PFX file with private key. |
| 107 | + PdfCertificate pdfCert = new PdfCertificate( filePath + "PDF.pfx", "password123"); |
| 108 | + |
| 109 | + //Creates a digital signature |
| 110 | + PdfSignature Signature = new PdfSignature(PDFViewer.LoadedDocument, page, pdfCert, "Signature"); |
| 111 | + |
| 112 | + //Sets an image for signature field |
| 113 | + PdfBitmap signatureImage = new PdfBitmap( filePath + "ESign.png"); |
| 114 | + |
| 115 | + // Center the signature on the click position using dimensions in points. |
| 116 | + float signWidth = signatureImage.PhysicalDimension.Width; |
| 117 | + float signHeight = signatureImage.PhysicalDimension.Height; |
| 118 | + Signature.Bounds = new System.Drawing.RectangleF((float)(x), (float)(y), signWidth, signHeight); |
| 119 | + |
| 120 | + Signature.ContactInfo = "[email protected]"; |
| 121 | + Signature.LocationInfo = "Honolulu, Hawaii"; |
| 122 | + Signature.Reason = "I am author of this document."; |
| 123 | + |
| 124 | + //Draws the signature image |
| 125 | + Signature.Appearance.Normal.Graphics.DrawImage(signatureImage, 0, 0); |
| 126 | + |
| 127 | + //Save the document into stream. |
| 128 | + MemoryStream stream = new MemoryStream(); |
| 129 | + PDFViewer.LoadedDocument.Save(stream); |
| 130 | + stream.Position = 0; |
| 131 | + |
| 132 | + //Reloads the document |
| 133 | + PDFViewer.Load(stream); |
| 134 | + addSignature = false; |
| 135 | + } |
| 136 | + |
| 137 | + } |
| 138 | + |
| 139 | + private void CreateSignatureImage() |
| 140 | + { |
| 141 | + int pageIndex = PDFViewer.CurrentPageIndex - 1; |
| 142 | + if(pageIndex < 0) |
| 143 | + return; |
| 144 | + |
| 145 | + //Creating image for current date and time details |
| 146 | + CreateCurrentDataImage(); |
| 147 | + |
| 148 | + //Combine the name image and date-time image into a single image |
| 149 | + CombineSignatureAndDataImage(); |
| 150 | + |
| 151 | + } |
| 152 | + |
| 153 | + private void CombineSignatureAndDataImage() |
| 154 | + { |
| 155 | + // Load the two images |
| 156 | + using (System.Drawing.Image nameImage = System.Drawing.Image.FromFile(filePath + "John.png")) |
| 157 | + using (System.Drawing.Image signImage = System.Drawing.Image.FromFile(filePath + "DigitalSignatureBlock.png")) |
| 158 | + { |
| 159 | + // Create a new bitmap with combined width and max height |
| 160 | + int signatureWidth = nameImage.Width + signImage.Width; |
| 161 | + int signatureHeight = Math.Max(nameImage.Height, signImage.Height); |
| 162 | + using (Bitmap combinedImage = new Bitmap(signatureWidth, signatureHeight)) |
| 163 | + using (Graphics g = System.Drawing.Graphics.FromImage(combinedImage)) |
| 164 | + { |
| 165 | + // Draw both images side by side |
| 166 | + g.DrawImage(nameImage, 0, 0); |
| 167 | + g.DrawImage(signImage, nameImage.Width, 0); |
| 168 | + // Save the result |
| 169 | + combinedImage.Save(filePath + "ESign.png", System.Drawing.Imaging.ImageFormat.Png); |
| 170 | + } |
| 171 | + } |
| 172 | + } |
| 173 | + |
| 174 | + private void CreateCurrentDataImage() |
| 175 | + { |
| 176 | + int width = 200; |
| 177 | + int height = 100; |
| 178 | + string signerName = "John"; |
| 179 | + string dateTime = DateTime.Now.ToString("yyyy.MM.dd\nHH:mm:ss zzz"); |
| 180 | + string text = $"Digitally signed by {signerName}\nDate: {dateTime}\n\n"; |
| 181 | + string outputPath = filePath + "DigitalSignatureBlock.png"; |
| 182 | + Directory.CreateDirectory(System.IO.Path.GetDirectoryName(outputPath)); |
| 183 | + using (Bitmap bitmap = new Bitmap(width, height)) |
| 184 | + { |
| 185 | + using (Graphics graphics = System.Drawing.Graphics.FromImage(bitmap)) |
| 186 | + { |
| 187 | + using (Font font = new Font("Arial", 9)) |
| 188 | + using (SolidBrush backgroundBrush = new SolidBrush(System.Drawing.Color.White)) |
| 189 | + { |
| 190 | + graphics.FillRectangle(backgroundBrush, 0, 0, width, height); |
| 191 | + RectangleF layoutRect = new RectangleF(10, 10, width - 20, height - 20); |
| 192 | + graphics.DrawString(text, font, System.Drawing.Brushes.Black, layoutRect); |
| 193 | + bitmap.Save(outputPath, System.Drawing.Imaging.ImageFormat.Png); |
| 194 | + } |
| 195 | + } |
| 196 | + } |
| 197 | + } |
| 198 | + } |
| 199 | +} |
0 commit comments