Search Wiki:
A CAPTCHA is a program that can generate and grade tests that humans can pass but current computer programs cannot. For example, humans can read distorted text as the one shown below, but current computer programs can't:
This program demonstrates a sample code to implement Captcha in ASP.net using An ASP.NET server control and GDI.

captchaImg.JPG

Download Code: DynamicCaptchaCode.zip


Steps to Create a captcha project
1. Create a new web application project
2. Add a cs file to the project "CatpchaImage.cs" and add following code to it

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Drawing;
using System.Drawing.Drawing2D;

public class CatpchaImage
{
public static string SESSION_CAPTCHA = "CAPTCHA";


const int default_width = 140;
const int default_height = 40;

protected Bitmap result = null;

public int Width;
public int Height;

public CatpchaImage()
{
InitBitmap(defaultwidth, defaultheight);
rnd = new Random();
}

public CatpchaImage(int width, int height)
{
InitBitmap(width, height);
}

protected void InitBitmap(int width, int height)
{
result = new Bitmap(width, height);
Width = width;
Height = height;
rnd = new Random();
}



public PointF Noise(PointF p, double eps)
{
p.X = Convert.ToSingle(rnd.NextDouble() * eps * 2 - eps) + p.X;
p.Y = Convert.ToSingle(rnd.NextDouble() * eps * 2 - eps) + p.Y;
return p;
}

public PointF Wave(PointF p, double amp, double size)
{
p.Y = Convert.ToSingle(Math.Sin(p.X / size) * amp) + p.Y;
p.X = Convert.ToSingle(Math.Sin(p.X / size) * amp) + p.X;
return p;
}



public GraphicsPath RandomWarp(GraphicsPath path)
{
// Add line //
int PsCount = 10;
PointF[] curvePs = new PointFPsCount 2;
for (int u = 0; u < PsCount; u++)
{
curvePsu.X = u * (Width / PsCount);
curvePsu.Y = Height / 2;
}
for (int u = PsCount; u < (PsCount 2); u++)
{
curvePsu.X = (u - PsCount) * (Width / PsCount);
curvePsu.Y = Height / 2 + 2;
}


double eps = Height * 0.05;

double amp = rnd.NextDouble() * (double)(Height / 3);
double size = rnd.NextDouble() * (double)(Width / 4) + Width / 8;

double offset = (double)(Height / 3);


PointF[] pn = new PointFpath.PointCount;
byte[] pt = new bytepath.PointCount;

GraphicsPath np2 = new GraphicsPath();

GraphicsPathIterator iter = new GraphicsPathIterator(path);
for (int i = 0; i < iter.SubpathCount; i++)
{
GraphicsPath sp = new GraphicsPath();
bool closed;
iter.NextSubpath(sp, out closed);

Matrix m = new Matrix();
m.RotateAt(Convert.ToSingle(rnd.NextDouble() * 30 - 15), sp.PathPoints0);

m.Translate(-1 * i, 0);//uncomment

sp.Transform(m);

np2.AddPath(sp, true);
}




for (int i = 0; i < np2.PointCount; i++)
{
//pni = Noise( path.PathPointsi , eps);
pni = Wave(np2.PathPointsi, amp, size);
pti = np2.PathTypesi;
}

GraphicsPath newpath = new GraphicsPath(pn, pt);

return newpath;

}

Random rnd;


public string DrawNumbers(int len)
{
string str = "";
string possible = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789abcdfghjkmnpqrstvwxyz";
char ch='A';
for (int i = 0; i < len; i++)
{
ch=possiblernd.Next(0, possible.Length -1);
str = str + ch.ToString();
}

DrawText(str);
return str;
}

public void DrawText(string aText)
{

Graphics g = Graphics.FromImage(result);
int startsize = Height;
Font f = new Font("Verdana", startsize, FontStyle.Bold, GraphicsUnit.Pixel);

do
{
f = new Font("Verdana", startsize, GraphicsUnit.Pixel);
startsize--;
} while ((g.MeasureString(aText, f).Width >= Width) || (g.MeasureString(aText, f).Height >= Height));
SizeF sf = g.MeasureString(aText, f);
int width = Convert.ToInt32(sf.Width);
int height = Convert.ToInt32(sf.Height);

int x = Convert.ToInt32(Math.Abs((double)width - (double)Width) * rnd.NextDouble());
int y = Convert.ToInt32(Math.Abs((double)height - (double)Height) * rnd.NextDouble());

//////// Paths ///
GraphicsPath path = new GraphicsPath(FillMode.Alternate);

FontFamily family = new FontFamily("Verdana");
int fontStyle = (int)(FontStyle.Regular);
float emSize = f.Size;
Point origin = new Point(x, y);
StringFormat format = StringFormat.GenericDefault;

path.AddString(aText, family, fontStyle, emSize, origin, format);


g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
Rectangle rect = new Rectangle(0, 0, Width, Height);
g.FillRectangle(new System.Drawing.Drawing2D.LinearGradientBrush(rect, Color.White, Color.White, 0f), rect);
g.SmoothingMode = SmoothingMode.HighQuality;


Color noiseCol = Color.FromArgb(100, 120, 180);
Pen p = new Pen(noiseCol);


/* generate random dots in background */
for( int i=0; i<(Width*Height)/3; i++ ) {
g.FillEllipse(Brushes.Blue, rnd.Next(0, Width), rnd.Next(0, Height), 1, 1);
}
/noise ends here/

/* generate random lines in background */
for( int i=0; i<(Width*Height)/150; i++ ) {
g.DrawLine(p,rnd.Next(0,Width), rnd.Next(0,Height), rnd.Next(0,Width), rnd.Next(0,Height));
}

Color textColor = Color.FromArgb(20, 40, 100);
g.FillPath(new SolidBrush(textColor), path);

g.Dispose();
}

public Bitmap Result
{
get
{
return result;
}
}


}





3. Add a ASP.NET server control to the project "captcha.ashx"

Add the following code to it

<%@ WebHandler Language="C#" Class="captcha" %>

using System;
using System.Web;
using System.Drawing;
using System.Web.SessionState;

public class captcha : IHttpHandler, IRequiresSessionState
{


public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "image/jpeg";
CatpchaImage captcha = new CatpchaImage();
string str = captcha.DrawNumbers(5);
if (context.Session CatpchaImage.SESSION_CAPTCHA == null) context.Session.Add(CatpchaImage.SESSION_CAPTCHA, str);
else
{
context.Session CatpchaImage.SESSION_CAPTCHA = str;
}
Bitmap bmp = captcha.Result;
bmp.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
}



public bool IsReusable {
get {
return true;
}
}

}








4. To the Default.aspx page add a Imagebox, Textbox and Button. Set property of image button : ImageUrl="~/captcha.ashx"



<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Image ID="ImgCaptcha" runat="server" ImageUrl="~/captcha.ashx" /><br />
Enter Verification Code
<asp:TextBox ID="txtInput" runat="server"></asp:TextBox><br />
<br />
<asp:Button ID="btnSubmit" runat="server" Text="Submit" OnClick="btnSubmit_Click" /><br />
<asp:Label ID="lblMessage" runat="server"></asp:Label></div>
</form>
</body>


5. Write the following code in the button click

protected void btnSubmit_Click(object sender, EventArgs e)
{
if (Session"CAPTCHA".ToString().Equals(txtInput.Text))
lblMessage.Text = "Valid Code Inputed";
else
lblMessage.Text = "InValid Code Inputed";

}
Last edited Jul 21 2009 at 7:26 AM  by prajithmp, version 7
Comments
SmartTech wrote  Oct 26 2010 at 7:32 PM  
How do you tie this in with the rest of the form asp validators? For example, when invalid code is entered into the captcha text box, the page does a postback and sends the form anyway. Then, the captcha give the message that the wong code was entered. How do you get it to validate before postback or stop the form from posting unless the captcha code is correct?

Help!!

Updating...
Page view tracker