none
inserting captcha image to web form RRS feed

  • Question

  • hi guys,

    i have an aspx web form with vb code behind. the form is a simple input form with a table with textboxes and a submit button. i am looking to be able to insert a captcha image into the table with an entry textbox and check the value entered against the image on the submit button.

    i have found various 'helpful' bits of code on the net to explain how to generate the image. but none of them explain exactly how/when the image would get generated, how you can insert the image onto the webform where you want it to be, or how you can check the text input against that image.

    any help would be most grateful.

    thanks in advance

    Wednesday, September 14, 2011 1:37 PM

Answers

  • Wrong forum (you want the asp.net site) but I can help regardless.  Here's the basic steps:

    1. You need some code that will create an image with text on it (I will provide some).
    2. You need to create a http handler (ashx) file.  This file will send the contents of the image you create and you can put it in your page as an IMG tag.
    3. You will want to keep the string value of what's in the image somewhere.

    This code I have is old, I don't like the way I used ByRef.. but it works. :p

    Captcha.vb

    Imports System
    Imports System.Text
    Imports System.Drawing
    Imports System.Drawing.Graphics
    Imports System.Drawing.Imaging
    Imports Microsoft.VisualBasic
    
        ''' <summary>
        ''' Class can be used to validate whether a user is a user or a bot.
        ''' </summary>
        ''' <remarks></remarks>
        ''' <dependencies>
        ''' System.Drawing
        ''' </dependencies>
        Public Class Captcha
            '*********************************************************************************************************************
            '
            '             Class:  Captcha
            '      Initial Date:  04/12/2008
            '      Last Updated:  04/14/2009
            '     Programmer(s):  Blake Pell
            '
            '*********************************************************************************************************************
    
            ''' <summary>
            ''' Constructor
            ''' </summary>
            ''' <remarks></remarks>
            Public Sub New()
    
            End Sub
    
            ''' <summary>
            ''' Creates the skewed image with text and puts it into a memory stream.
            ''' </summary>
            ''' <param name="MemoryStream"></param>
            ''' <remarks></remarks>
            Public Sub CreateImage(ByRef memoryStream As System.IO.MemoryStream)
                _text = GetRandomText()
                Dim bitmap As New Bitmap(200, 50, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
                Dim g As Graphics
                g = Graphics.FromImage(bitmap)
                Dim rect As New Rectangle(0, 0, 200, 70)
                Dim counter As Integer = 0
                g.FillRectangle(Brushes.DarkKhaki, rect)
                Dim i As Integer
                For i = 0 To _text.Length - 1
                    g.DrawString(_text(i).ToString, _font, GetRandomBrush, New PointF(10 + counter, 10))
                    counter += 20
                Next
                DrawRandomLines(g)
                bitmap.Save(memoryStream, ImageFormat.Jpeg)
    
                ' Cleanup            
                g.Dispose()
                bitmap.Dispose()
            End Sub
    
            ''' <summary>
            ''' Draws random lines via a graphics object.
            ''' </summary>
            ''' <param name="g"></param>
            ''' <remarks></remarks>
            Private Sub DrawRandomLines(ByVal g As Graphics)
                Dim i As Integer
                For i = 0 To 10
                    g.DrawLine(New Pen(Color.Gray, 1), GetRandomPoint(), GetRandomPoint2())
                Next
            End Sub
    
            ''' <summary>
            ''' Gets a random point within the top half of the image boundaries
            ''' </summary>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Private Function GetRandomPoint() As Point
                Return New Point(_random.Next(0, 100), _random.Next(1, 25))
            End Function
    
            ''' <summary>
            ''' Gets a random point within the bottom half of the image boundaries
            ''' </summary>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Private Function GetRandomPoint2() As Point
                Return New Point(_random.Next(101, 200), _random.Next(26, 50))
            End Function
    
            ''' <summary>
            ''' Gets a random brush color
            ''' </summary>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Private Function GetRandomBrush() As Brush
                Select Case _random.Next(1, 5)
                    Case 1
                        Return Brushes.Blue
                    Case 2
                        Return Brushes.Black
                    Case 3
                        Return Brushes.Red
                    Case 4
                        Return Brushes.Green
                    Case 5
                        Return Brushes.Maroon
                    Case Else
                        Return Brushes.White
                End Select
            End Function
    
            ''' <summary>
            ''' Gets random text.
            ''' </summary>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Private Function GetRandomText() As String
                Dim randomText As New StringBuilder
                Dim characterSet As String = "abcdefghijklmnopqrstuvwxyz23456789"
                For counter As Integer = 0 To 7
                    randomText.Append(characterSet(_random.Next(characterSet.Length)))
                Next
                Return randomText.ToString
            End Function
    
            '**********************************************************************************************
            '  Properties and class variables
            '**********************************************************************************************
    
            ''' <summary>
            ''' Random number generator.
            ''' </summary>
            ''' <remarks></remarks>
            Private _random As New System.Random
    
            Private _text As String = ""
            ''' <summary>
            ''' Text to display on the image.
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks>Currently, this is set to the value of the GetRandomText function when the CreateImage procedure is run.</remarks>
            Public Property Text() As String
                Get
                    Return _text
                End Get
                Set(ByVal value As String)
                    _text = value
                End Set
            End Property
    
            Private _fontSize As Integer = 10
            ''' <summary>
            ''' The font size to use on the image.
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks>The default font size is 10</remarks>
            Public Property FontSize() As Integer
                Get
                    Return _fontSize
                End Get
                Set(ByVal value As Integer)
                    _fontSize = value
                End Set
            End Property
    
            Private _font As New Font("Courier New", _fontSize + _random.Next(14, 18), FontStyle.Bold)
            ''' <summary>
            ''' The font to use on the image.
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks>The default font is Courier New.</remarks>
            Public Property Font() As Font
                Get
                    Return _font
                End Get
                Set(ByVal value As Font)
                    _font = value
                End Set
            End Property
    
        End Class
    
    

    Captcha.ashx

    <%@ WebHandler Language="VB" Class="ShowImage" %>
    
    Imports System
    Imports System.Web
    Imports System.IO
    
    Public Class ShowImage : Implements IHttpHandler : Implements System.Web.SessionState.IRequiresSessionState
        
        Public Sub ProcessRequest(ByVal Context As HttpContext) Implements IHttpHandler.ProcessRequest
            Dim captcha As New Captcha()
            Dim ms As New System.IO.MemoryStream
            captcha.CreateImage(Ms)
            Context.Session("Captcha") = captcha.Text
            Context.Response.ContentType = "image/jpeg"
            Context.Response.BinaryWrite(ms.ToArray)
        End Sub
      
        Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
            Get
                Return False
            End Get
        End Property
      
    End Class
    

    You can put this image on your web form like this:

    <img src="captcha.ashx" />
    
    At this point, you can compare the value in the session "Captcha" property to what the user entered. 

    • Marked as answer by morgannus Thursday, September 15, 2011 11:27 AM
    Wednesday, September 14, 2011 4:05 PM

All replies

  • Wrong forum (you want the asp.net site) but I can help regardless.  Here's the basic steps:

    1. You need some code that will create an image with text on it (I will provide some).
    2. You need to create a http handler (ashx) file.  This file will send the contents of the image you create and you can put it in your page as an IMG tag.
    3. You will want to keep the string value of what's in the image somewhere.

    This code I have is old, I don't like the way I used ByRef.. but it works. :p

    Captcha.vb

    Imports System
    Imports System.Text
    Imports System.Drawing
    Imports System.Drawing.Graphics
    Imports System.Drawing.Imaging
    Imports Microsoft.VisualBasic
    
        ''' <summary>
        ''' Class can be used to validate whether a user is a user or a bot.
        ''' </summary>
        ''' <remarks></remarks>
        ''' <dependencies>
        ''' System.Drawing
        ''' </dependencies>
        Public Class Captcha
            '*********************************************************************************************************************
            '
            '             Class:  Captcha
            '      Initial Date:  04/12/2008
            '      Last Updated:  04/14/2009
            '     Programmer(s):  Blake Pell
            '
            '*********************************************************************************************************************
    
            ''' <summary>
            ''' Constructor
            ''' </summary>
            ''' <remarks></remarks>
            Public Sub New()
    
            End Sub
    
            ''' <summary>
            ''' Creates the skewed image with text and puts it into a memory stream.
            ''' </summary>
            ''' <param name="MemoryStream"></param>
            ''' <remarks></remarks>
            Public Sub CreateImage(ByRef memoryStream As System.IO.MemoryStream)
                _text = GetRandomText()
                Dim bitmap As New Bitmap(200, 50, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
                Dim g As Graphics
                g = Graphics.FromImage(bitmap)
                Dim rect As New Rectangle(0, 0, 200, 70)
                Dim counter As Integer = 0
                g.FillRectangle(Brushes.DarkKhaki, rect)
                Dim i As Integer
                For i = 0 To _text.Length - 1
                    g.DrawString(_text(i).ToString, _font, GetRandomBrush, New PointF(10 + counter, 10))
                    counter += 20
                Next
                DrawRandomLines(g)
                bitmap.Save(memoryStream, ImageFormat.Jpeg)
    
                ' Cleanup            
                g.Dispose()
                bitmap.Dispose()
            End Sub
    
            ''' <summary>
            ''' Draws random lines via a graphics object.
            ''' </summary>
            ''' <param name="g"></param>
            ''' <remarks></remarks>
            Private Sub DrawRandomLines(ByVal g As Graphics)
                Dim i As Integer
                For i = 0 To 10
                    g.DrawLine(New Pen(Color.Gray, 1), GetRandomPoint(), GetRandomPoint2())
                Next
            End Sub
    
            ''' <summary>
            ''' Gets a random point within the top half of the image boundaries
            ''' </summary>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Private Function GetRandomPoint() As Point
                Return New Point(_random.Next(0, 100), _random.Next(1, 25))
            End Function
    
            ''' <summary>
            ''' Gets a random point within the bottom half of the image boundaries
            ''' </summary>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Private Function GetRandomPoint2() As Point
                Return New Point(_random.Next(101, 200), _random.Next(26, 50))
            End Function
    
            ''' <summary>
            ''' Gets a random brush color
            ''' </summary>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Private Function GetRandomBrush() As Brush
                Select Case _random.Next(1, 5)
                    Case 1
                        Return Brushes.Blue
                    Case 2
                        Return Brushes.Black
                    Case 3
                        Return Brushes.Red
                    Case 4
                        Return Brushes.Green
                    Case 5
                        Return Brushes.Maroon
                    Case Else
                        Return Brushes.White
                End Select
            End Function
    
            ''' <summary>
            ''' Gets random text.
            ''' </summary>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Private Function GetRandomText() As String
                Dim randomText As New StringBuilder
                Dim characterSet As String = "abcdefghijklmnopqrstuvwxyz23456789"
                For counter As Integer = 0 To 7
                    randomText.Append(characterSet(_random.Next(characterSet.Length)))
                Next
                Return randomText.ToString
            End Function
    
            '**********************************************************************************************
            '  Properties and class variables
            '**********************************************************************************************
    
            ''' <summary>
            ''' Random number generator.
            ''' </summary>
            ''' <remarks></remarks>
            Private _random As New System.Random
    
            Private _text As String = ""
            ''' <summary>
            ''' Text to display on the image.
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks>Currently, this is set to the value of the GetRandomText function when the CreateImage procedure is run.</remarks>
            Public Property Text() As String
                Get
                    Return _text
                End Get
                Set(ByVal value As String)
                    _text = value
                End Set
            End Property
    
            Private _fontSize As Integer = 10
            ''' <summary>
            ''' The font size to use on the image.
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks>The default font size is 10</remarks>
            Public Property FontSize() As Integer
                Get
                    Return _fontSize
                End Get
                Set(ByVal value As Integer)
                    _fontSize = value
                End Set
            End Property
    
            Private _font As New Font("Courier New", _fontSize + _random.Next(14, 18), FontStyle.Bold)
            ''' <summary>
            ''' The font to use on the image.
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks>The default font is Courier New.</remarks>
            Public Property Font() As Font
                Get
                    Return _font
                End Get
                Set(ByVal value As Font)
                    _font = value
                End Set
            End Property
    
        End Class
    
    

    Captcha.ashx

    <%@ WebHandler Language="VB" Class="ShowImage" %>
    
    Imports System
    Imports System.Web
    Imports System.IO
    
    Public Class ShowImage : Implements IHttpHandler : Implements System.Web.SessionState.IRequiresSessionState
        
        Public Sub ProcessRequest(ByVal Context As HttpContext) Implements IHttpHandler.ProcessRequest
            Dim captcha As New Captcha()
            Dim ms As New System.IO.MemoryStream
            captcha.CreateImage(Ms)
            Context.Session("Captcha") = captcha.Text
            Context.Response.ContentType = "image/jpeg"
            Context.Response.BinaryWrite(ms.ToArray)
        End Sub
      
        Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
            Get
                Return False
            End Get
        End Property
      
    End Class
    

    You can put this image on your web form like this:

    <img src="captcha.ashx" />
    
    At this point, you can compare the value in the session "Captcha" property to what the user entered. 

    • Marked as answer by morgannus Thursday, September 15, 2011 11:27 AM
    Wednesday, September 14, 2011 4:05 PM
  • bpell,

    thanks for your reply, sorry for the post being in the wrong place.

    i understand the theory of the vb but i'm still pretty new to .asp so please forgive me.

    the project i am working on was all written in plain html files, with no real functionality. i was tasked to update the information on it and correct the contact form so the only .asp is on the contact form. ive now realised i need another slightly different contact form so i would need the catpcha code in its own code file and then call on it when required and save the text in a global variable so i can retrieve that when required also.

    i understand that this is possible and you have already given me the code for this(thank you) but as i said i am still new to .asp and am unsure of where things go exactly and how to call them when required.

    so, do i create a basic vb file with the captcha code in it that gets called from the ashx file which in turn is called from the img src? and is the captcha.text a public variable so i can reference it on the submit button code behind like 'if textbox.text = captcha.text'?

    oh, in case it helps, the structure of the site:-

    root directory - index page, webconfig, bin folder(containing dll files), Pages folder(containing my html & aspx files), Images folder(cantaining all my jpg & gif files)

    once again thank you for your help and patience


    • Edited by morgannus Thursday, September 15, 2011 8:58 AM
    Thursday, September 15, 2011 8:42 AM
  • ok got it working now.

    i inserted the newly created .vb and .ashx files in my pages folder in the root directory and on the captcha.ashx instead of this line:-

    Dim captcha As New Captcha()
    


    i had to use :-

       Dim captcha As New YourProjectName.Captcha()
    
    
    

    also on the codebehind for the submit button to check the text entered i used this code :-

      If textbox.text =  Session("Captcha") Then
          ' do whatever you need to do
      End If
    
    

    so once again thank pbell for all your help

     

    Thursday, September 15, 2011 1:18 PM
  • Glad it helped. :)
    Friday, September 16, 2011 4:35 PM