February 12, 2009

Create Text Images on the Fly with ASP.NET

The .NET framework makes the task of generating and manipulating images on the fly very easy. And for classical ASP developers, gone are the days when they had to rely on third party components to generate and manipulate images dynamically. Now they can use .NET framework classes to draw images and render text in a variety of formats.

The following code sample demonstrates how you can use the built-in ASP.NET classes to generate a graphical representation of a single line of text. The example is quite intuitive and only uses three parameters: (1) the text (2) font size and (3) font color. The generated graphic is a 256 color GIF image with transparency. This example includes a palette hack for forcing a transparent background on the GIF image -- some .NET coders seem to have problems doing that.

The Complete Code

<%@ Page Language="VB" ContentType="image/gif" Debug="true" Explicit="true" %>
<%@ Import Namespace="System.Drawing" %>
<%@ Import Namespace="System.Drawing.Imaging" %>
<%@ Import Namespace="System.IO" %>
<script runat="server">

  ' ASP.NET Text to Images Script
  ' Revision 2 [2010-03-01]
  ' Revised the transparency hack to use heuristics

  Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)

    ' Capture and sanitize querystring parameters

    Dim qText As String
    qText = Request.QueryString("text")
    If qText = String.Empty Then
      qText = "-"
    End If

    Dim qSize As Integer
      qSize = Request.QueryString("size")
      qSize = 0
    End Try
    If qSize < 8 Then
      qSize = 8
    End If

    Dim qColor As String
    qColor = Request.QueryString("color")
    If qColor = String.Empty OrElse Regex.IsMatch(qColor, "^[0-9A-F]{6}$", RegexOptions.IgnoreCase) = False Then
      qColor = "000000"
    End If

    ' Call the function

    RenderGraphic(qText, qSize, qColor)

  End Sub

  Private Sub RenderGraphic(ByVal pText As String, ByVal pSize As Integer, ByVal pColor As String)

    ' Declare and pre-calculate the variables

    Dim b As Bitmap = New Bitmap(1, 1)
    Dim g As Graphics = Graphics.FromImage(b)
    Dim f As Font = New Font("Arial", pSize)
    Dim w As Integer = g.MeasureString(pText, f).Width
    Dim h As Integer = g.MeasureString(pText, f).Height
    Dim c1 As Color = ColorTranslator.FromHtml("#" & pColor)
    Dim c2 As Color = IIf(c1.GetBrightness < 0.5, Color.FromArgb(&HFF00FFFF), Color.FromArgb(&HFF330000))

    ' Render drawing

    b = New Bitmap(w, h)
    g = Graphics.FromImage(b)
    g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit
    g.DrawString(pText, f, New SolidBrush(c1), 0, 0)

    ' Save in memory

    Dim m As New MemoryStream
    b.Save(m, ImageFormat.Gif)

    ' Apply transparency hack
    ' For the background, we choose one of these two colors from the stubborn GIF
    ' palette: #00FFFF (@75) for dark text or #330000 (@76) for bright text
    ' We then set this color as transparent by hacking into the GIF palette

    Dim n As Byte()
    n = m.ToArray()
    n(787) = IIf(c1.GetBrightness < 0.5, 75, 76)

    ' Send to browser

    Dim o As New BinaryWriter(Response.OutputStream)

  End Sub


Example Output

  1. text-gif.aspx?text=hello+world&size=32&color=ffcc00
    Hello World (FFCC00)
  2. text-gif.aspx?text=hello+world&size=64&color=ff0000
    Hello World (FF0000)


This code sample is known to work with .NET framework version 2.x

With some modifications, you can use this script to replace (obfuscate) email addresses on your website with GIF images. This makes it difficult for email harvesters and spam bots to extract email addresses from the content. Example:

This image has an email address written on it
This image has an email address written on it

UTF-8 encoded text in the query-string turned out to be working just fine:
This image has Arabic text written on it