Click here to Skip to main content
15,892,697 members
Articles / Web Development / ASP.NET

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 99.2K   2.2K   70  
How to perform simple web image annotation using ASP.NET.
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;


namespace ImageMarkup
{
	/// <summary>
	/// Summary description for WebForm1.
	/// </summary>
	public class WebForm1 : System.Web.UI.Page
	{
		protected System.Web.UI.WebControls.DropDownList listType;
		protected System.Web.UI.WebControls.TextBox txtParam;
		protected System.Web.UI.WebControls.Button btnRemove;
		protected System.Web.UI.WebControls.TextBox txtRemove;
		protected System.Web.UI.WebControls.Label lblExample;
		protected System.Web.UI.WebControls.ImageButton MarkupImage;
	
		private void Page_Load(object sender, System.EventArgs e)
		{
			// Put user code to initialize the page here
			if (!IsPostBack)
			{
				// Bind the dropdown list
				DataTable tbl = GetMarkTypeTable();
				listType.DataSource = tbl;
				listType.DataValueField = "value";
				listType.DataTextField = "desc";
				listType.DataBind();

				// Create javascript for displaying example text
				string script = "<script language=javascript> function getExample() {";
				script += "var examples = new Array(" + tbl.Rows.Count.ToString() + ");";
				for(int i=1; i<tbl.Rows.Count; i++)
				{
					script += "examples[" + tbl.Rows[i]["value"] + "]=\"" + tbl.Rows[i]["example"] + "\";";
				}
				script += "document.getElementById(\"lblExample\").innerHTML=";
				script += "examples[document.getElementById(\"listType\").value]; }";
				script += "</script>";
				Session["ExampleScript"] = script;
			}

			// Register client-side javascript for displaying example text
			string javascript = Session["ExampleScript"] as string;
			if (javascript != null)
			{
				Page.RegisterStartupScript("getExample", javascript);
				listType.Attributes.Add("onChange", "getExample()");
			}
			
			// Retrieve x and y where the mouse click took place
			string x=Request.Params["MarkupImage.x"];
			string y=Request.Params["MarkupImage.y"];
			// Get type of annotation selected
			string type = listType.SelectedValue;
			// Get any applicable argument
			string param = txtParam.Text;
			// Create the MarkableType
			MarkableType mark = MarkManager.CreateByID(type);
			if (mark!=null && param.Length > 0)
			{
				mark.LoadFromString(param);
			}
			// Construct the new ImageURL
			if (x !=null && y !=null && x.Length>=0 && y.Length>=0 && mark!=null)
			{
				string append = string.Join(",", new string[] {x, y, type, mark.SaveAsString()});
				MarkupImage.ImageUrl += HttpUtility.HtmlEncode(append + ";");
			}
		}
		
		private DataTable GetMarkTypeTable()
		{
			DataTable tbl = new DataTable();

			DataColumn col = new DataColumn("value", Type.GetType("System.String"));
			tbl.Columns.Add(col);

			col = new DataColumn("desc", Type.GetType("System.String"));
			tbl.Columns.Add(col);

			col = new DataColumn("example", Type.GetType("System.String"));
			tbl.Columns.Add(col);

			DataRow row = tbl.NewRow();
			row["value"] = "-1";
			row["desc"] = "";
			row["example"] = "";
			tbl.Rows.Add(row);

			row = tbl.NewRow();
			row["value"] = "0";
			row["desc"] = "Rectangle";
			row["example"] = "format: 'width,height'. eg. 5,6";
			tbl.Rows.Add(row);

			row = tbl.NewRow();
			row["value"] = "1";
			row["desc"] = "Circle";
			row["example"] = "format: 'radius'. eg. 10";
			tbl.Rows.Add(row);

			row = tbl.NewRow();
			row["value"] = "2";
			row["desc"] = "Text";
			row["example"] = "format: 'text'.";
			tbl.Rows.Add(row);

			row = tbl.NewRow();
			row["value"] = "3";
			row["desc"] = "Image";
			row["example"] = "format: 'image.jpg'. Type eg. left.ico, right.ico, stop.ico. Relative to the current directory";
			tbl.Rows.Add(row);

			tbl.AcceptChanges();
			
			return tbl;
		}


		#region Web Form Designer generated code
		override protected void OnInit(EventArgs e)
		{
			//
			// CODEGEN: This call is required by the ASP.NET Web Form Designer.
			//
			InitializeComponent();
			base.OnInit(e);
		}
		
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{    
			this.btnRemove.Click += new System.EventHandler(this.btnRemove_Click);
			this.Load += new System.EventHandler(this.Page_Load);

		}
		#endregion

		private void btnRemove_Click(object sender, System.EventArgs e)
		{
			// To remove an item, simply remove its corresponding part in MarkupImage.ImageUrl

			if (txtRemove.Text.Length <= 0)
			{
				return;
			}

			string url = HttpUtility.HtmlDecode(MarkupImage.ImageUrl);

			int id = -1;
			try
			{
				id = int.Parse(txtRemove.Text);
			}
			catch{}

			int pos1=url.IndexOf("?desc=") + 5; 
			int pos2=-1;
			// pos1 is to the right of pos2
			while (id>=0)
			{
				pos2 = pos1;
				pos1 = url.IndexOf(";", System.Math.Max(0, pos2+1)); // non-negative
				if (pos1>=0)
				{
					id--;
				}
				else
				{
					// did not find the id
					return;
				}
			}

			// discard between pos2+1 and pos1, inclusive
			MarkupImage.ImageUrl = url.Remove(pos2+1, pos1-pos2);
		}

	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

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