ASP.NET - C# - Dynamic text image control

Posted Sep 21, 2009 by CodeGolem / comments 0 comments / Print / Font Size Decrease font size Increase font size

Many programmers already use GDI functionalities to dynamically render images 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 tags point to the fake page as the image source. What about turning it all into a handy and reusable Custom Control?

A FULLY CODE-FORMATTED COPY OF THIS ARTICLE IS AVAILABLE ON THE CODEGOLEM BLOG

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.

[code:c#]
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();
        }
    }
}
[/code]

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:

[code:html]
<httpHandlers>
    <add path="image.ashx" verb="GET" type="DynamicImage.ImageRenderer"/>
</httpHandlers>
[/code]

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.

[code:c#]
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));
        }
    }
}
[/code]

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

[code:html]
<pages>
 <controls>
         <add tagPrefix="my" namespace="DynamicImage" assembly="DynamicImage" />
 </controls>
</pages>
[/code]

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

[code:html]
<%@ 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>
[/code]

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!

Rate this Article:

Be the first to rate me.


* You must be logged in order to leave comments, please login or join us.

Comments

No comments yet.



Bookmark and Share
Sign up for our email newsletter
Name:
Email: