-
Notifications
You must be signed in to change notification settings - Fork 5
Added sample for E signing in PDF document using WPF PDFViewer #69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
eed9512
Added sample for E signing in PDF document using WPF PDFViewer
YathavakrishnanMohan adb221a
Feed back changes
YathavakrishnanMohan f9fbb9b
Feedback changes
YathavakrishnanMohan ba5ff5b
Feedback changes
YathavakrishnanMohan f71aa04
Feedback changes
YathavakrishnanMohan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<configuration> | ||
<startup> | ||
|
||
</startup> | ||
</configuration> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<Application x:Class="PDFViewer_WPF.App" | ||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
xmlns:local="clr-namespace:PDFViewer_WPF" | ||
StartupUri="MainWindow.xaml"> | ||
<Application.Resources> | ||
|
||
</Application.Resources> | ||
</Application> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Configuration; | ||
using System.Data; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using System.Windows; | ||
|
||
namespace PDFViewer_WPF | ||
{ | ||
/// <summary> | ||
/// Interaction logic for App.xaml | ||
/// </summary> | ||
public partial class App : Application | ||
{ | ||
} | ||
} |
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<Window xmlns:syncfusion="http://schemas.syncfusion.com/wpf" xmlns:PdfViewer="clr-namespace:Syncfusion.Windows.PdfViewer;assembly=Syncfusion.PdfViewer.WPF" x:Class="WPF_Sample_FW.MainWindow" | ||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | ||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | ||
xmlns:local="clr-namespace:WPF_Sample_FW" | ||
mc:Ignorable="d" | ||
Title="MainWindow" Height="450" Width="800"> | ||
<Grid> | ||
<PdfViewer:PdfViewerControl Name="PDFViewer" PageClicked="PDFViewer_PageClicked"/> | ||
|
||
</Grid> | ||
</Window> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
using Syncfusion.Pdf; | ||
using Syncfusion.Pdf.Graphics; | ||
using Syncfusion.Pdf.Security; | ||
using Syncfusion.Windows.PdfViewer; | ||
using System; | ||
using System.Drawing; | ||
using System.IO; | ||
using System.Windows; | ||
using System.Windows.Controls; | ||
using System.Windows.Media; | ||
using Path = System.Windows.Shapes.Path; | ||
using Bitmap = System.Drawing.Bitmap; | ||
|
||
namespace WPF_Sample_FW | ||
{ | ||
/// <summary> | ||
/// Interaction logic for MainWindow.xaml | ||
/// </summary> | ||
public partial class MainWindow : Window | ||
{ | ||
string filePath = "../../../Data/"; | ||
bool addSignature = false; | ||
public MainWindow() | ||
{ | ||
InitializeComponent(); | ||
PDFViewer.Load(filePath + "Ink signature.pdf"); | ||
PDFViewer.Loaded += PDFViewer_Loaded; | ||
PDFViewer.ZoomMode = ZoomMode.FitPage; | ||
} | ||
|
||
private void PDFViewer_Loaded(object sender, RoutedEventArgs e) | ||
{ | ||
// Find the default toolbar from the PDFViewer control template. | ||
DocumentToolbar toolbar = PDFViewer.Template.FindName("PART_Toolbar", PDFViewer) as DocumentToolbar; | ||
|
||
// Find the stack panel inside the toolbar where buttons are arranged. | ||
StackPanel stackPanel = (StackPanel)toolbar.Template.FindName("PART_ToolbarStack", toolbar); | ||
|
||
// Get the last stack panel in the toolbar stack (usually contains default buttons). | ||
StackPanel stack = stackPanel.Children[stackPanel.Children.Count - 1] as StackPanel; | ||
|
||
// Get the first button from the stack to copy its style and icon. | ||
Button button = stack.Children[0] as Button; | ||
Path oldStylePath = button.Content as Path; | ||
|
||
Button eSignButton = GetButton(oldStylePath, button); | ||
|
||
// Add the new eSign button to the toolbar stack. | ||
stackPanel.Children.Add(eSignButton); | ||
} | ||
|
||
private void eSignButton_Click(object sender, RoutedEventArgs e) | ||
{ | ||
addSignature = true; | ||
} | ||
|
||
private Button GetButton(System.Windows.Shapes.Path oldPath, Button button) | ||
{ | ||
// Create a new custom button for eSign functionality. | ||
Button eSignButton = new Button(); | ||
|
||
// Create a new Path object to use as the icon for the eSign button. | ||
Path path = new Path(); | ||
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"); | ||
|
||
// Copy the fill color from the existing button's icon. | ||
path.Fill = oldPath.Fill; | ||
|
||
// Set the icon as the content of the new button. | ||
eSignButton.Content = path; | ||
|
||
// Match the icon's size and layout to the original button. | ||
path.Stretch = Stretch.Uniform; | ||
path.Height = oldPath.Height; | ||
path.Width = oldPath.Width; | ||
|
||
// Match the button's background and layout properties to the original button. | ||
eSignButton.Height = button.Height; | ||
eSignButton.Width = button.Width; | ||
eSignButton.Margin = button.Margin; | ||
eSignButton.Style = button.Style; | ||
// Attach the click event handler for eSign functionality. | ||
eSignButton.Click += eSignButton_Click; | ||
|
||
return eSignButton; | ||
} | ||
|
||
private void PDFViewer_PageClicked(object sender, PageClickedEventArgs args) | ||
{ | ||
if (addSignature) | ||
{ | ||
int pageIndex = PDFViewer.CurrentPageIndex - 1; | ||
CreateSignatureImage(); | ||
|
||
//Gets the first page of the document | ||
PdfLoadedPage page = PDFViewer.LoadedDocument.Pages[pageIndex] as PdfLoadedPage; | ||
|
||
//Retrieve the clicked client area position | ||
System.Windows.Point clientPoint = args.Position; | ||
|
||
// Convert client point to page point, which accounts for zoom mode. | ||
System.Windows.Point pagePoint = PDFViewer.ConvertClientPointToPagePoint(clientPoint, pageIndex + 1); | ||
double x = pagePoint.X; | ||
double y = pagePoint.Y; | ||
|
||
//Creates a certificate instance from PFX file with private key. | ||
PdfCertificate pdfCert = new PdfCertificate( filePath + "PDF.pfx", "password123"); | ||
|
||
//Creates a digital signature | ||
PdfSignature Signature = new PdfSignature(PDFViewer.LoadedDocument, page, pdfCert, "Signature"); | ||
|
||
//Sets an image for signature field | ||
PdfBitmap signatureImage = new PdfBitmap( filePath + "ESign.png"); | ||
|
||
// Center the signature on the click position using dimensions in points. | ||
float signWidth = signatureImage.PhysicalDimension.Width; | ||
float signHeight = signatureImage.PhysicalDimension.Height; | ||
Signature.Bounds = new System.Drawing.RectangleF((float)(x), (float)(y), signWidth, signHeight); | ||
|
||
Signature.ContactInfo = "johndoe@owned.us"; | ||
Signature.LocationInfo = "Honolulu, Hawaii"; | ||
Signature.Reason = "I am author of this document."; | ||
|
||
//Draws the signature image | ||
Signature.Appearance.Normal.Graphics.DrawImage(signatureImage, 0, 0); | ||
|
||
//Save the document into stream. | ||
MemoryStream stream = new MemoryStream(); | ||
PDFViewer.LoadedDocument.Save(stream); | ||
stream.Position = 0; | ||
|
||
//Reloads the document | ||
PDFViewer.Load(stream); | ||
addSignature = false; | ||
} | ||
|
||
} | ||
|
||
private void CreateSignatureImage() | ||
{ | ||
int pageIndex = PDFViewer.CurrentPageIndex - 1; | ||
if(pageIndex < 0) | ||
return; | ||
|
||
//Creating image for current date and time details | ||
CreateCurrentDataImage(); | ||
|
||
//Combine the name image and date-time image into a single image | ||
CombineSignatureAndDataImage(); | ||
|
||
} | ||
|
||
private void CombineSignatureAndDataImage() | ||
{ | ||
// Load the two images | ||
using (System.Drawing.Image nameImage = System.Drawing.Image.FromFile(filePath + "John.png")) | ||
using (System.Drawing.Image signImage = System.Drawing.Image.FromFile(filePath + "DigitalSignatureBlock.png")) | ||
{ | ||
// Create a new bitmap with combined width and max height | ||
int signatureWidth = nameImage.Width + signImage.Width; | ||
int signatureHeight = Math.Max(nameImage.Height, signImage.Height); | ||
using (Bitmap combinedImage = new Bitmap(signatureWidth, signatureHeight)) | ||
using (Graphics g = System.Drawing.Graphics.FromImage(combinedImage)) | ||
{ | ||
// Draw both images side by side | ||
g.DrawImage(nameImage, 0, 0); | ||
g.DrawImage(signImage, nameImage.Width, 0); | ||
// Save the result | ||
combinedImage.Save(filePath + "ESign.png", System.Drawing.Imaging.ImageFormat.Png); | ||
} | ||
} | ||
} | ||
|
||
private void CreateCurrentDataImage() | ||
{ | ||
int width = 200; | ||
int height = 100; | ||
string signerName = "John"; | ||
string dateTime = DateTime.Now.ToString("yyyy.MM.dd\nHH:mm:ss zzz"); | ||
string text = $"Digitally signed by {signerName}\nDate: {dateTime}\n\n"; | ||
string outputPath = filePath + "DigitalSignatureBlock.png"; | ||
Directory.CreateDirectory(System.IO.Path.GetDirectoryName(outputPath)); | ||
using (Bitmap bitmap = new Bitmap(width, height)) | ||
{ | ||
using (Graphics graphics = System.Drawing.Graphics.FromImage(bitmap)) | ||
{ | ||
using (Font font = new Font("Arial", 9)) | ||
using (SolidBrush backgroundBrush = new SolidBrush(System.Drawing.Color.White)) | ||
{ | ||
graphics.FillRectangle(backgroundBrush, 0, 0, width, height); | ||
RectangleF layoutRect = new RectangleF(10, 10, width - 20, height - 20); | ||
graphics.DrawString(text, font, System.Drawing.Brushes.Black, layoutRect); | ||
bitmap.Save(outputPath, System.Drawing.Imaging.ImageFormat.Png); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>WinExe</OutputType> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Syncfusion.PdfViewer.WPF" Version="*" /> | ||
<PackageReference Include="System.Drawing.Common" Version="9.0.8" /> | ||
</ItemGroup> | ||
<Import Project="targets\MultiTargeting.targets" /> | ||
</Project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
| ||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 17 | ||
VisualStudioVersion = 17.14.36401.2 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PDFViewer_WPF", "PDFViewer_WPF.csproj", "{0FAA7523-B034-4EA9-860A-A8936DFFD40E}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{0FAA7523-B034-4EA9-860A-A8936DFFD40E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{0FAA7523-B034-4EA9-860A-A8936DFFD40E}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{0FAA7523-B034-4EA9-860A-A8936DFFD40E}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{0FAA7523-B034-4EA9-860A-A8936DFFD40E}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {BAAD6341-6945-42C7-8438-919E9DB8EB03} | ||
EndGlobalSection | ||
EndGlobal |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
using System.Reflection; | ||
using System.Resources; | ||
using System.Runtime.CompilerServices; | ||
using System.Runtime.InteropServices; | ||
using System.Windows; | ||
|
||
// General Information about an assembly is controlled through the following | ||
// set of attributes. Change these attribute values to modify the information | ||
// associated with an assembly. | ||
//[assembly: AssemblyTitle("PDFViewer_WPF")] | ||
//[assembly: AssemblyDescription("")] | ||
//[assembly: AssemblyConfiguration("")] | ||
//[assembly: AssemblyCompany("")] | ||
//[assembly: AssemblyProduct("PDFViewer_WPF")] | ||
//[assembly: AssemblyCopyright("Copyright © 2025")] | ||
//[assembly: AssemblyTrademark("")] | ||
//[assembly: AssemblyCulture("")] | ||
|
||
// Setting ComVisible to false makes the types in this assembly not visible | ||
// to COM components. If you need to access a type in this assembly from | ||
// COM, set the ComVisible attribute to true on that type. | ||
[assembly: ComVisible(false)] | ||
|
||
//In order to begin building localizable applications, set | ||
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file | ||
//inside a <PropertyGroup>. For example, if you are using US english | ||
//in your source files, set the <UICulture> to en-US. Then uncomment | ||
//the NeutralResourceLanguage attribute below. Update the "en-US" in | ||
//the line below to match the UICulture setting in the project file. | ||
|
||
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] | ||
|
||
|
||
//[assembly: ThemeInfo( | ||
// ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located | ||
// //(used if a resource is not found in the page, | ||
// // or application resource dictionaries) | ||
// ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located | ||
// //(used if a resource is not found in the page, | ||
// // app, or any theme specific resource dictionaries) | ||
//)] | ||
|
||
|
||
// Version information for an assembly consists of the following four values: | ||
// | ||
// Major Version | ||
// Minor Version | ||
// Build Number | ||
// Revision | ||
// | ||
//[assembly: AssemblyVersion("1.0.0.0")] | ||
//[assembly: AssemblyFileVersion("1.0.0.0")] |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
even split "CreateSignatureImage" method , as text image creation as one and combining two images as another.