an ASP.NET, C# technical blog, by Gianni Tropiano

Dynamic text image control

by CodeGolem 6. May 2009 21:16

Many of us already use GDI functionalities to dynamically render an image on the server with some custom font.

I bet most of you just create a fake ASPX page that creates the image, then you make your <img> or <asp:Image> tags point to the fake page as the image source.

What about turning it all into a handy and reusable Custom Control?

Let's start with a new control library and put in a HttpHandler.
We will use it to render the image and output as binary data to the OutputStream.

It will be just a class implementing the IHttpHandler interface.
Everything we would do in the page's Load event must be done within the ProcessRequest method in our handler.

Here is a sample.


using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.Web;

namespace DynamicImage
{
    class ImageRenderer : IHttpHandler
    {
        private string _text
        {
            get { return HttpContext.Current.Request["text"]; }
        }

        private string _fontName
        {
            get { return HttpContext.Current.Request.QueryString["fontName"]; }
        }

        private int _fontSize
        {
            get { return int.Parse(HttpContext.Current.Request.QueryString["fontSize"]); }
        }

        private Color _foreColor
        {
            get { return ColorTranslator.FromHtml(HttpContext.Current.Request.QueryString["foreColor"]); }
        }

        private Color _backColor
        {
            get { return ColorTranslator.FromHtml(HttpContext.Current.Request.QueryString["backColor"]); }
        }

        public bool IsReusable
        {
            get { return false; }
        }

        public void ProcessRequest(HttpContext context)
        {
            // fake bitmap to get needed size
            Bitmap bitmap = new Bitmap(1, 1);

            int width = 0;
            int height = 0;

            // create font object with requested properties
            Font font = new Font(_fontName,
                _fontSize,
                FontStyle.Regular);

            // create the graphics object to measure text size and perform actual rendering
            Graphics graphics = Graphics.FromImage(bitmap);

            // get needed size to render the wanted text
            SizeF size = graphics.MeasureString(_text, font);
            width = (int)size.Width;
            height = (int)size.Height;

            // release resources
            graphics.Dispose();
            bitmap.Dispose();

            // create the actual bitmap with final size
            bitmap = new Bitmap(width, height);

            // render text
            graphics = Graphics.FromImage(bitmap);
            graphics.Clear(_backColor);
            graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
            graphics.DrawString(_text,
                font,
                new SolidBrush(_foreColor),
                0,
                0);
            graphics.Flush();

            // create codec object for jpg format
            ImageCodecInfo jpegCodec = null;
            foreach (ImageCodecInfo codec in ImageCodecInfo.GetImageEncoders())
                if (codec.MimeType == "image/jpeg")
                {
                    jpegCodec = codec;
                    break;
                }

            // set codec quality
            EncoderParameters parameters = new EncoderParameters(1);
            parameters.Param[0] = new EncoderParameter(Encoder.Quality, (long)100);

            // output the binary data to the output stream
            bitmap.Save(context.Response.OutputStream, jpegCodec, parameters);

            // release resources
            graphics.Dispose();
            bitmap.Dispose();
        }
    }
}

Now, to test the handler, we create a new Web project, add a reference to our newly created Control Library, and register our HttpHandler in web.config file as follows:


<httpHandlers>
    <add path="image.ashx" verb="GET" type="DynamicImage.ImageRenderer"/>
</httpHandlers>

Let's get it working in the browser.
Navigate to the following path in your test site:

image.ashx?text=Hello World&fontName=Verdana&fontSize=18&foreColor=yellow&backColor=red

This should render the "Hello World" text with a yellow-on-red color.

Fine, this was the first step, nothing really new.

Now we are going to add a WebControl that will encapsulate the rendering functionalities, just converting a series of custom properties to the correct url.

Let's add a new server control to the library.


using System;
using System.ComponentModel;
using System.Drawing;
using System.Web.UI;

namespace DynamicImage
{
    [DefaultProperty("Text")]
    [ToolboxData("<{0}:DynamicImage runat=server></{0}:DynamicImage>")]
    public class DynamicImage : System.Web.UI.WebControls.Image
    {
        public string Text { get; set; }
        public string FontName { get; set; }
        public int FontSize { get; set; }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            ImageUrl = string.Format("image.ashx?text={0}&fontName={1}&fontSize={2}&foreColor={3}&backColor={4}",
                Text,
                FontName,
                FontSize,
                ColorTranslator.ToHtml(ForeColor),
                ColorTranslator.ToHtml(BackColor));
        }
    }
}

Last step: register the custom control in our test site web.config file:


<pages>
 <controls>
         <add tagPrefix="my" namespace="DynamicImage" assembly="DynamicImage" />
 </controls>
</pages>

We are done! Let's try it out on a page:


<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="DynamicImage_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>My Dynamic Image</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        This is my dynamic image:
       
        <my:DynamicImage
            runat="server"
            Text="Hello World"
            FontName="Verdana"
            FontSize="18"
            ForeColor="Yellow"
            BackColor="Red"
            />
    </div>
    </form>
</body>
</html>

That's it. Now we have a dynamic image renderer, which we can easily reuse in any project of ours.

Hope you will find it useful in your web applications.

Happy coding!

Source code available here: DynamicImage.zip (3.27 kb)

Tags: ,

ASP.NET

Comments


United States Judith 
August 3. 2009 23:20
I just would like to thanks for the blog. Like it. Thanks.


United States dentist hungary 
August 3. 2009 23:21
Great job mate! I like your work. Thanks for sharing


United States color correction 
February 5. 2010 07:23
Thanks mate.. good blog

Add comment



  Country flag

biuquote
  • Comment
  • Preview
Loading



Sponsored by

LiveCo®
Silverlight® based
video conferencing platform

Hosting provided by

Lineadigitale