I want to create an image with text for verification, similar to the ones used in Google, Yahoo in user registration. How can I create this?

The HTML markup for the sample page with image verification will look like something like this:


<form id="form1" runat="server">
<div>
    <asp:Image ID="VerImage" runat="server" ImageUrl="~/ImageViewer.ashx"/>
    <asp:TextBox ID="VerText" runat="server" />
    <asp:CustomValidator id="VerifyVal" runat="server" ValidateEmptyText="true" 
	ControlToValidate="VerText" OnServerValidate="VerifyVal_ServerValidate">*
    </asp:CustomValidator>
    <asp:Button Text="Verify" runat="server" />
</div>
</form>

The image is rendered using a ImageViewer.ashx handler. The textbox text is verified using a CustomValidator. In the server-side, we handle the Page load event and CustomValidator ServerValidate event. In the Page load event we create a verification text and store it in a session variable. In the ServerValidate event, we pick the verification text from the Session variable and validate the text in the textbox. The code is as below:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        string verText = "Sample";
        Session["Verify"] = verText;
    }
}

protected void VerifyVal_ServerValidate(object source, ServerValidateEventArgs args)
{
    args.IsValid = false;
    string verText = (string)Session["Verify"];
    if (!String.IsNullOrEmpty(verText))
    {
        if (VerText.Text == verText)
        {
            args.IsValid = true;
        }
    }
}

The image rendering is performed in a handler class - ImageViewer.ashx. The ProcessRequest method gets the verification text from the session variable. This is possible only if the handler class derives from IRequiresSessionState (System.Web.SessionState). IRequiresSessionState is a marker interface. So, no new methods have to be defined.

After getting the verification text, an image object is created from a background image file. Using the graphics object of the image object, we can draw the string. Once the string is drawn, the image object can be streamed into the Response object. The code for the handler is below:


public class ImageViewer : IHttpHandler, IRequiresSessionState
{

    public void ProcessRequest(HttpContext context)
    {    
        Image image = Image.FromFile(context.Server.MapPath("~/red.jpg"));
        Graphics gp = Graphics.FromImage(image);

        string text = "Default";
        if (context.Session!=null && context.Session["Verify"]!=null)
            text = (string)context.Session["Verify"];

        Font font = new Font(new FontFamily("Arial"), image.Height/3);
        Brush brush = Brushes.White;
        PointF point = new PointF(image.Width/4, image.Height/4);
        gp.DrawString(text, font, brush, point);

        image.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif);
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}