1: <%@ WebHandler Language="C#" Class="CaptchaImages" %>
2:
3: /*
4: * File: CaptchaImages.ashx
5: * Author: Simon Jarvis
6: * Copyright: 2006 Simon Jarvis
7: * Date: 03/08/06
8: * Updated: 07/02/07
9: * Requirements: PHP 4/5 with GD and FreeType libraries
10: * Link: http://www.white-hat-web-design.co.uk/articles/php-captcha.php
11: *
12: * This program is free software; you can redistribute it and/or
13: * modify it under the terms of the GNU General Public License
14: * as published by the Free Software Foundation; either version 2
15: * of the License, or (at your option) any later version.
16: *
17: * This program is distributed in the hope that it will be useful,
18: * but WITHOUT ANY WARRANTY; without even the implied warranty of
19: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20: * GNU General Public License for more details:
21: * http://www.gnu.org/licenses/gpl.html
22: *
23: * C# Version for ASP.NET
24: * Author: Robert S. Robbins
25: * Modified: 06/10/08
26: * Requirements: ASP.NET 2.0 with GD-Sharp
27: */
28:
29: using System;
30: using System.Web;
31: using System.Diagnostics;
32: using System.Collections;
33: using System.IO;
34: using System.Drawing;
35: using Ntx.GD;
36:
37: public class CaptchaImages : IHttpHandler { 38:
39: private string font_file = @"C:\\WINDOWS\\Fonts\\bauhs93.ttf";
40: private string font_name = "Bauhaus 93";
41: private string mime_type = "image/jpeg";
42: private bool transparent_background = true;
43:
44: public void ProcessRequest (HttpContext context) { 45: // create trace listener file for debugging purposes
46: System.IO.Stream objFile = System.IO.File.Create(@"C:\Inetpub\wwwroot\study\App_Data\trace2.txt");
47: TextWriterTraceListener objTextListener = new TextWriterTraceListener(objFile);
48: Trace.Listeners.Add(objTextListener);
49: Trace.AutoFlush = true;
50:
51: GD image = CaptchaSecurityImage(120, 40, 6);
52:
53: /* output captcha image to browser */
54: context.Response.ContentType = mime_type;
55: MemoryStream ms = new MemoryStream();
56: image.Save(GD.FileType.Jpeg, ms);
57: byte[] binary = ms.ToArray();
58: context.Response.BinaryWrite(binary);
59: context.Response.Flush();
60:
61: Trace.Close();
62: Trace.Flush();
63: }
64:
65: /// <summary>
66: /// Generates a random code with the specified number of characters.
67: /// </summary>
68: /// <param name="characters">The number of characters to generate.</param>
69: /// <returns>A random code.</returns>
70: public string generateCode(int characters)
71: { 72: /* list all possible characters, similar looking characters and vowels have been removed */
73: string possible = "23456789bcdfghjkmnpqrstvwxyz";
74: string code = "";
75: int i = 0;
76: Random random = new Random();
77: while (i < characters)
78: { 79: int intRandomNumber = random.Next(0, possible.Length);
80: Trace.WriteLine(intRandomNumber.ToString(), "intRandomNumber");
81: code += possible.Substring(intRandomNumber, 1);
82: i++;
83: }
84: return code;
85: }
86:
87: public GD CaptchaSecurityImage(int width, int height, int characters)
88: { 89: string code = generateCode(characters);
90: /* font size will be 75% of the image height */
91: int font_size = Convert.ToInt32(height * 0.75);
92: // This is the equivalent of calling ImageCreate
93: GD image = new GD(width, height, false);
94: /* set the colours */
95: /* The first color in a new image should be the background color
96: * but it requires trueColor to be set to false*/
97: GDColor background_color = image.ColorAllocate(255, 255, 255);
98: GDColor text_color = image.ColorAllocate(20, 40, 100);
99: GDColor noise_color = image.ColorAllocate(100, 120, 180);
100: Random random = new Random();
101: /* generate random dots in background */
102: for (int i = 0; i < (width * height) / 3; i++)
103: { 104: int intRandomNumberX = random.Next(0, width);
105: int intRandomNumberY = random.Next(0, height);
106: image.FilledEllipse(intRandomNumberX, intRandomNumberY, 2, 2, noise_color);
107: }
108: /* generate random lines in background */
109: for (int i = 0; i < (width * height) / 150; i++)
110: { 111: int intRandomNumberX = random.Next(0, width);
112: int intRandomNumberY = random.Next(0, height);
113: int intRandomNumberX2 = random.Next(0, width);
114: int intRandomNumberY2 = random.Next(0, height);
115: image.Line(intRandomNumberX, intRandomNumberY, intRandomNumberX2, intRandomNumberY2, noise_color);
116: }
117: /* create textbox and add text */
118: int[] textbox = ImageTTFBBox(font_name, font_size, code);
119: // bounding rectangle
120: ArrayList br = new ArrayList();
121: br.Add(new Ntx.GD.Point(0, 0));
122: br.Add(new Ntx.GD.Point(textbox[0], 0));
123: br.Add(new Ntx.GD.Point(textbox[0], textbox[1]));
124: br.Add(new Ntx.GD.Point(0, textbox[1]));
125: /* font size will be 75% of the image height */
126: font_size = Convert.ToInt32(textbox[1] * 0.75);
127: // This is the equivalent of calling ImageTTFText
128: string result = image.StringFT(br, text_color, font_file, font_size, 0, 0, font_size, code, true);
129: Trace.WriteLine(result, "result");
130:
131: // set transparency
132: if (transparent_background)
133: { 134: image.ColorTransparent(background_color);
135: }
136:
137: return image;
138: }
139:
140: /// <summary>
141: /// Give the bounding box of a text using TrueType fonts
142: /// </summary>
143: /// <param name="font">The name of a TTF font.</param>
144: /// <param name="size">The size of the font.</param>
145: /// <param name="text">The text to be displayed using the font.</param>
146: /// <returns>An integer array containing the height and width.</returns>
147: /// <remarks>Not exactly the same as the original function, but the best we can do.</remarks>
148: public int[] ImageTTFBBox(string font, int size, string text)
149: { 150: Bitmap objBmpImage = new Bitmap(1, 1);
151:
152: int intWidth = 0;
153: int intHeight = 0;
154:
155: System.Drawing.Font objFont = new System.Drawing.Font(font, size, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel);
156:
157: // Create a graphics object to measure the text’s width and height.
158: Graphics objGraphics = Graphics.FromImage(objBmpImage);
159:
160: // Determine the bitmap size.
161: /* Need to multiply the width by 2.0.
162: * This is an ugly hack.
163: * The System.Drawing width will not match the GD Library drawing width.
164: */
165: intWidth = Convert.ToInt32(objGraphics.MeasureString(text, objFont).Width * 2.0);
166: intHeight = Convert.ToInt32(objGraphics.MeasureString(text, objFont).Height);
167: Trace.WriteLine(intWidth.ToString(), "intWidth");
168: Trace.WriteLine(intHeight.ToString(), "intHeight");
169: int[] box = { intWidth, intHeight }; 170: return box;
171: }
172:
173: public bool IsReusable { 174: get { 175: return false;
176: }
177: }
178:
179: }