├── README.md
└── SignatureToImage.cs
/README.md:
--------------------------------------------------------------------------------
1 | #Signature to Image .Net
2 | **License:** BSD License
3 | **Version:** 2.0 (2012-02-11)
4 | **Requirements:** .NET 4.0
5 |
6 | A supplemental class for Signature Pad (https://github.com/thomasjbradley/signature-pad) that generates an image of the signature's JSON output server-side using C#. Alternately, you can provide a name and generate an image that resembles a signature from a font. Similar to Signature to Image PHP (https://github.com/thomasjbradley/signature-to-image)
7 |
8 | ##Creating image based on Json
9 | If you want to regenerate the signature based on the Json generated by Signature Pad you just need to call the `SigJsonToImage` method like so:
10 |
11 | var sigToImg = new SignatureToImage();
12 | var signatureImage = sigToImg.SigJsonToImage(signatureJson);
13 |
14 | ##Creating image based on name
15 | Similar to using Json, if the user typed their name instead of using the pen, just pass in their name to the `SigNameToImage` method and it will use a font to regenerate the signature:
16 |
17 | var sigToImg = new SignatureToImage();
18 | var signatureImage = sigToImg.SigNameToImage("Sir John A. Macdonald");
19 |
20 | By default, the font "Journal" will be used. You probably already have the font file in your project as Signature Pad required it. If you do not have the Journal font installed on your server you can pass in the absolute path to the font file as an optional parameter:
21 |
22 | var sigToImg = new SignatureToImage();
23 | var signatureImage = sigToImg.SigNameToImage("Sir John A. Macdonald", fontPath: HttpContext.Current.Request.PhysicalApplicationPath + @"Resources\journal.ttf");
24 |
25 | ##Properties
26 | The default values are shown below, but you can change any or all of them as you wish (`PenWidth`, `FontSize`, and `FontName` only apply to `SigNameToImage`):
27 |
28 | var sigToImg = new SignatureToImage({
29 | BackgroundColor = System.Drawing.Color.White,
30 | PenColor = System.Drawing.Color.FromArgb(20, 83, 148),
31 | CanvasWidth = 198,
32 | CanvasHeight = 45,
33 | PenWidth = 2,
34 | FontSize = 24,
35 | FontName = "Journal"
36 | });
37 | var signatureImage = sigToImg.SigNameToImage("Sir John A. Macdonald");
38 |
--------------------------------------------------------------------------------
/SignatureToImage.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Author: Curtis Herbert (me@forgottenexpanse.com)
3 | * License: BSD License
4 | * Version: 2.0 (2012-02-11)
5 | * Contributor: Justin Stolle (justin@justinstolle.com)
6 | */
7 |
8 | using System;
9 | using System.Collections.Generic;
10 | using System.Drawing;
11 | using System.Drawing.Drawing2D;
12 | using System.Drawing.Text;
13 | using System.IO;
14 | using System.Linq;
15 | using System.Web.Script.Serialization;
16 |
17 | namespace ConsumedByCode.SignatureToImage
18 | {
19 | ///
20 | /// A supplemental class for Signature Pad (https://github.com/thomasjbradley/signature-pad)
21 | /// that generates an image of the signature's JSON output server-side using C#. Alternately,
22 | /// you can provide a name and generate an image that resembles a signature from a font.
23 | /// Similar to Signature to Image PHP (https://github.com/thomasjbradley/signature-to-image)
24 | ///
25 | public class SignatureToImage
26 | {
27 | public Color BackgroundColor { get; set; }
28 | public Color PenColor { get; set; }
29 | public int CanvasWidth { get; set; }
30 | public int CanvasHeight { get; set; }
31 | public float PenWidth { get; set; }
32 | public float FontSize { get; set; }
33 | public string FontName { get; set; }
34 |
35 | ///
36 | /// Gets a new signature generator with the default options.
37 | ///
38 | public SignatureToImage()
39 | {
40 | // Default values
41 | BackgroundColor = Color.White;
42 | PenColor = Color.FromArgb(20, 83, 148);
43 | CanvasWidth = 198;
44 | CanvasHeight = 45;
45 | PenWidth = 2;
46 | FontSize = 24;
47 | FontName = "Journal";
48 | }
49 |
50 | ///
51 | /// Draws a signature based on the JSON provided by Signature Pad.
52 | ///
53 | /// JSON string of line drawing commands.
54 | /// Bitmap image containing the signature.
55 | public Bitmap SigJsonToImage(string json)
56 | {
57 | return SigJsonToImage(json, new Size(CanvasWidth, CanvasHeight));
58 | }
59 |
60 | ///
61 | /// Draws a signature based on the JSON provided by Signature Pad.
62 | ///
63 | /// JSON string of line drawing commands.
64 | /// System.Drawing.Size structure containing Width and Height dimensions.
65 | /// Bitmap image containing the signature.
66 | public Bitmap SigJsonToImage(string json, Size size)
67 | {
68 | var signatureImage = GetBlankCanvas();
69 | if (!string.IsNullOrWhiteSpace(json))
70 | {
71 | using (var signatureGraphic = Graphics.FromImage(signatureImage))
72 | {
73 | signatureGraphic.SmoothingMode = SmoothingMode.AntiAlias;
74 | var pen = new Pen(PenColor, PenWidth);
75 | var serializer = new JavaScriptSerializer();
76 | // Next line may throw System.ArgumentException if the string
77 | // is an invalid json primitive for the SignatureLine structure
78 | var lines = serializer.Deserialize>(json);
79 | foreach (var line in lines)
80 | {
81 | signatureGraphic.DrawLine(pen, line.lx, line.ly, line.mx, line.my);
82 | }
83 | }
84 | }
85 | return (Bitmap)((size.Width == CanvasWidth && size.Height == CanvasHeight) ? signatureImage : ResizeImage(signatureImage, size));
86 | }
87 |
88 | ///
89 | /// Draws an approximation of a signature using a font.
90 | ///
91 | /// The string that will be drawn.
92 | /// Full path of font file to be used if default font is not installed on the system.
93 | /// Bitmap image containing the user's signature.
94 | public Bitmap SigNameToImage(string name, string fontPath = null)
95 | {
96 | return SigNameToImage(name, null, fontPath);
97 | }
98 |
99 | ///
100 | /// Draws an approximation of a signature using a font.
101 | ///
102 | /// The string that will be drawn.
103 | /// System.Drawing.Size structure containing Width and Height dimensions.
104 | /// Full path of font file to be used if default font is not installed on the system.
105 | /// Bitmap image containing the user's signature.
106 | public Bitmap SigNameToImage(string name, Size size, string fontPath = null)
107 | {
108 | var signatureImage = GetBlankCanvas();
109 | if (!string.IsNullOrWhiteSpace(name))
110 | {
111 | Font font;
112 | // Need a reference to the font, be it the .ttf in the project or the system-installed font
113 | if (string.IsNullOrWhiteSpace(fontPath))
114 | {
115 | // Path parameter not provided, try to use system-installed font
116 | var installedFontCollection = new InstalledFontCollection();
117 | if (installedFontCollection.Families.Any(f => f.Name == FontName))
118 | {
119 | font = new Font(FontName, FontSize);
120 | }
121 | else
122 | {
123 | throw new ArgumentException("The full path of the font file must be provided when the specified font is not installed on the system.", "fontPath");
124 | }
125 | }
126 | else if (File.Exists(fontPath))
127 | {
128 | try
129 | {
130 | // Temporarily install font while not affecting the system-installed collection
131 | var collection = new PrivateFontCollection();
132 | collection.AddFontFile(fontPath);
133 | font = new Font(collection.Families.First(), FontSize);
134 | }
135 | catch (FileNotFoundException)
136 | {
137 | // Since the existence of the file has already been tested, this exception
138 | // means the file is invalid or not supported when trying to load
139 | throw new Exception("The specified font file \"" + fontPath + "\" is either invalid or not supported.");
140 | }
141 | }
142 | else
143 | {
144 | throw new FileNotFoundException("The specified font file \"" + fontPath + "\" does not exist or permission was denied.", fontPath);
145 | }
146 | using (var signatureGraphic = Graphics.FromImage(signatureImage))
147 | {
148 | signatureGraphic.TextRenderingHint = TextRenderingHint.AntiAlias;
149 | signatureGraphic.DrawString(name, font, new SolidBrush(PenColor), 0, 0);
150 | }
151 | }
152 | return (Bitmap)((size.Width == CanvasWidth && size.Height == CanvasHeight) ? signatureImage : ResizeImage(signatureImage, size));
153 | }
154 |
155 | ///
156 | /// Get a blank bitmap using instance properties for dimensions and background color.
157 | ///
158 | /// Blank bitmap image.
159 | private Bitmap GetBlankCanvas()
160 | {
161 | var blankImage = new Bitmap(CanvasWidth, CanvasHeight);
162 | blankImage.MakeTransparent();
163 | using (var signatureGraphic = Graphics.FromImage(blankImage))
164 | {
165 | signatureGraphic.Clear(BackgroundColor);
166 | }
167 | return blankImage;
168 | }
169 |
170 | ///
171 | /// Resizes the image to fit the canvas in the event that the signature was drawn larger than it will be redisplayed.
172 | ///
173 | /// The image that will be resized.
174 | /// System.Drawing.Size structure containing the new Width and Height dimensions.
175 | /// Resized image.
176 | private Image ResizeImage(Image img, Size size)
177 | {
178 | int srcWidth = img.Width;
179 | int srcHeight = img.Height;
180 |
181 | float percent = 0;
182 | float percWidth = 0;
183 | float percHeight = 0;
184 |
185 | percWidth = ((float)size.Width / (float)srcWidth);
186 | percHeight = ((float)size.Height / (float)srcHeight);
187 | percent = (percHeight < percWidth) ? percHeight : percWidth;
188 |
189 | int destWidth = (int)(srcWidth * percent);
190 | int destHeight = (int)(srcHeight * percent);
191 |
192 | Bitmap bmp = new Bitmap(destWidth, destHeight);
193 |
194 | Graphics graphic = Graphics.FromImage((Image)bmp);
195 | graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
196 | graphic.DrawImage(img, 0, 0, destWidth, destHeight);
197 | graphic.Dispose();
198 |
199 | return (Image)bmp;
200 | }
201 |
202 | ///
203 | /// Line drawing commands as generated by the Signature Pad JSON export option.
204 | ///
205 | private class SignatureLine
206 | {
207 | public int lx { get; set; }
208 | public int ly { get; set; }
209 | public int mx { get; set; }
210 | public int my { get; set; }
211 | }
212 | }
213 | }
214 |
--------------------------------------------------------------------------------