Click here to Skip to main content
15,868,292 members
Articles / Web Development / ASP.NET
Article

Image Annotation/Markup on the Web using ASP.NET

Rate me:
Please Sign up or sign in to vote.
4.83/5 (17 votes)
5 Oct 20043 min read 98.8K   2.2K   70   13
How to perform simple web image annotation using ASP.NET.

Sample Image - imgant.png

Introduction

A picture is worth thousands of words. This is especially true when filling certain web forms of situation-describing nature where an image could illustrate the main text effectively. Situations such as insurance form filling (car, house), or diagnosis (machinery, patient), situation assessment (accident, traffic, map), etc. would love to see simple image annotation capabilities added to the existing online web forms. In this article, I will show you a simple and effective way to annotate images on the web form, using ASP.NET.

How it works

To tackle such a problem, we divide it into two requirements:

  1. enable the image on the form to receive (x, y) coordinates as positions of the annotation;
  2. enable the server-side code to draw appropriate overlay onto the original image and render it to the browser.

Now does this sound a lot simpler?

For (1), we do not need to embed any client-side ActiveX component etc. to record simple (x, y) coordinates resulted from mouse clicks. <asp:ImageButton> would do the job very well. It supports an onClick(object sender, ImageClickEventArgs e) event. Properties of the e event argument object are:

  • e.x (integer) - X coordinate where the click took place.
  • e.y (integer) - Y coordinate where the click took place.

Or even simpler, after we create a server-side ImageButton in the form:

ASP.NET
<asp:ImageButton id="MarkupImage" runat="server" 
      ImageUrl="Markup.aspx?desc="></asp:ImageButton>

calling the next two lines would retrieve the required (x, y) coordinate information on the server side.

C#
string x=Request.Params["MarkupImage.x"];
string y=Request.Params["MarkupImage.y"];

Now (2). If the user selects a type of annotation (e.g., rectangle) and supply relevant arguments (e.g., width and height), he/she would click once on the image to add the annotation. After getting the (x, y) information from the mouse click, we would update the ImageUrl property of the ImageButton and make it point to another aspx file Markup.aspx that is responsible for rendering the original image with any overlay or annotation specified at the position of mouse click. For simplicity, all markup/annotation information including position, type and applicable arguments are encoded as a single URL parameter desc, each annotation object being semicolon delimited. For example, it could be:

C#
ImageUrl="Markup.aspx?desc=136,187,0,8,8;267," + 
         "254,1,3;138,282,2,TEXT;269,336,3,left.ico;";
//Format: "x,y,type,argument...;"
//Type  : 0 - rectangle, 1 - circle, 2 - text, 3 - server side image

It consists of four markups. The first one is "136,187,0,8,8;" being a rectangle of 8x8 at (136,187). The second one is "267,254,1,3;" being a circle of radius=3 at (267,254). The third one "138,282,2,TEXT;" means a 'TEXT' string at (138,282), while the last one "269,336,3,left.ico;" draws the image 'left.ico' onto (269,336); the file left.ico is on the server.

Setting ImageURL would cause the src attribute of the rendered HTML <input type="image"> in the browser pointing to Markup.aspx and that page is requested. Rendering the image is quite simple as we can load and manipulate images through the GDI+ managed class interface (a set of wrappers of Win32 GDI+ API).

C#
private void Page_Load(object sender, System.EventArgs e)
{
     string desc = HttpUtility.HtmlDecode(Request.Params["desc"]);
     if (desc == null)
     {
          desc = string.Empty;
     }
     MarkupImage("LocalMap.jpg", desc);
}


private void MarkupImage(string image, string desc)

{
    Bitmap bitmap = new Bitmap(Server.MapPath(image));
    MemoryStream memStream = new MemoryStream();
    Graphics g = Graphics.FromImage(bitmap);

    // ... Draw various annotations. omitted for clarity

    // Set the content type
    Response.Clear();
    Response.ContentType="image/jpeg";
    
    // Send the bitmap to the output stream
    bitmap.Save(memStream, ImageFormat.Jpeg);
    memStream.WriteTo(Response.OutputStream);

    // Cleanup
    g.Dispose();
    bitmap.Dispose();
}

Simple, isn't it?

The drawing for each type of annotation such as rectangle, circle, text, image etc. is using standard GDI+ functions, therefore would not be discussed in detail here and please refer to the source code. Of course, you could easily support many other types.

Points of Interest

In this article, we explored a mechanism to perform simple image annotation in the ASP.NET web form. It is achieved by reading the positional information of mouse click from the ImageButton control and assigning its ImageUrl attribute to another ASP.NET page with annotation information encoded into the URL parameter. The second page would subsequently render using GDI+ on the server-side and output it to the browser with ContentType="image/jpeg". This functionality could be useful in situations to complement pure text web to illustrate details worth thousands of words.

History

  • Sep-Oct 2004, first draft.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Singapore Singapore
I work in the software service industry. I love to build decision support systems embracing operations research and machine intelligence.

In my spare time I enjoy writing interesting proof-of-concept applications in many flavors of technologies as well as reading AI in game development. I watch many films. Many titles from Criterion Collection are my beloved, from Kurosawa, Tarkovsky, Kubrick, Ozu, film noir classic, you name it.

Presently I stay in Singapore and is a regular in http://www.sgdotnet.org (Singapore DotNet User Group), and I also write from time to time at http://community.sgdotnet.org/blogs/blackinkbottles_ink/default.aspx. Drop by if you can.

Comments and Discussions

 
General:) Pin
deathrow8-Sep-08 20:18
deathrow8-Sep-08 20:18 
GeneralRe: :) Pin
LionKing57712-Apr-10 20:54
LionKing57712-Apr-10 20:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.