///////////////////////////////////////////////////////////////////////////////
//
// ImageMarkerList.cs
//
// By Philip R. Braica (HoshiKata@aol.com, VeryMadSci@gmail.com)
//
// Distributed under the The Code Project Open License (CPOL)
// http://www.codeproject.com/info/cpol10.aspx
///////////////////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
namespace OpenCVDemo
{
public class ImageMarkerList
{
/// <summary>
/// Marker list.
/// </summary>
protected List<marker> m_list = new List<marker>();
/// <summary>
/// Clear.
/// </summary>
public void Clear() { m_list.Clear(); }
/// <summary>
/// Add text and point.
/// </summary>
/// <param name="text"></param>
/// <param name="p"></param>
public void Add(string text, System.Drawing.Point p)
{
m_list.Add(new marker(text, p));
}
/// <summary>
/// Add text and point.
/// </summary>
/// <param name="text"></param>
/// <param name="p"></param>
public void Add(string text, System.Drawing.PointF p)
{
Add(text, new System.Drawing.Point((int)p.X, (int)p.Y));
}
/// <summary>
/// Add text and rectangle.
/// </summary>
/// <param name="text"></param>
/// <param name="r"></param>
public void Add(string text, System.Drawing.Rectangle r)
{
m_list.Add(new marker(text, r));
}
/// <summary>
/// Add text and rectangle.
/// </summary>
/// <param name="text"></param>
/// <param name="r"></param>
public void Add(string text, System.Drawing.RectangleF r)
{
Add(text, new System.Drawing.Rectangle((int)r.Left, (int)r.Top, (int)r.Width, (int)r.Height));
}
/// <summary>
/// Render.
/// </summary>
/// <param name="b"></param>
/// <param name="stemLength"></param>
/// <param name="opacity"></param>
public void Render(System.Drawing.Bitmap b, Font f)
{
Render(b, f, 16, 0.7f);
}
/// <summary>
/// Render.
/// </summary>
/// <param name="b"></param>
/// <param name="stemLength"></param>
/// <param name="opacity"></param>
public void Render(System.Drawing.Bitmap b, Font f, int stemLength, float opacity)
{
int w = b.Width;
int h = b.Height;
System.Drawing.Color [] clrs = {
Color.Red, Color.Blue, Color.Green, Color.Orange, Color.Purple, Color.Brown,
Color.Cyan, Color.Magenta, Color.Aqua, Color.GreenYellow,
Color.Gray, Color.Crimson, Color.BlueViolet, Color.Olive,
Color.OrangeRed, Color.Plum, Color.PeachPuff, Color.PaleTurquoise, Color.Orchid,
Color.SandyBrown, Color.RoyalBlue, Color.Lime, Color.Violet, Color.DarkCyan};
int op = (int)(255 * opacity);
op = op < 0 ? op : op > 255 ? 255 : op;
using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(b))
{
for (int i = 0; i < m_list.Count; i++)
{
Color c = Color.FromArgb(op, clrs[i%clrs.Length]);
float angle = 11.61f * ((4095 * i) % 31);
m_list[i].Draw(g, f, c, w, h, stemLength, angle);
}
}
}
/// <summary>
/// Marker inernal class.
/// </summary>
protected class marker
{
/// <summary>
/// Draw.
/// </summary>
/// <param name="g"></param>
/// <param name="c"></param>
/// <param name="w"></param>
/// <param name="h"></param>
/// <param name="stemLength"></param>
/// <param name="angle"></param>
public void Draw(System.Drawing.Graphics g, Font f, Color c, int w, int h, int stemLength, float angle)
{
string text = Text;
angle = angle * (float)System.Math.PI / 180f;
Point src = new Point();
Point dst = new Point();
int radius = 4;
if (!IsRect)
{
src = new Point(
(int)(Location.X + ((stemLength) * System.Math.Cos(angle))),
(int)(Location.Y + ((stemLength) * System.Math.Sin(angle))));
dst = new Point(
(int)(Location.X + ((radius + stemLength) * System.Math.Cos(angle))),
(int)(Location.Y + ((radius + stemLength) * System.Math.Sin(angle))));
}
else
{
if (angle < System.Math.PI/2)
{
// Top right corner.
src = new Point(Rectangle.Right, Rectangle.Top);
}
if ((angle >= System.Math.PI/2) && (angle < System.Math.PI))
{
// Top left corner.
src = new Point(Rectangle.Left, Rectangle.Top);
}
if ((angle >= System.Math.PI) && (angle < 3*System.Math.PI/2))
{
// Bottom left corner.
src = new Point(Rectangle.Left, Rectangle.Bottom);
}
if (angle >= 3*System.Math.PI/2)
{
// Bottom right corner.
src = new Point(Rectangle.Right, Rectangle.Bottom);
}
dst = new Point(
(int)(src.X + ((stemLength) * System.Math.Cos(angle))),
(int)(src.Y + ((stemLength) * System.Math.Sin(angle))));
}
if ((text.Length > 0) && (f != null))
{
SizeF sf = g.MeasureString(text, f);
using (Pen p = new Pen(c, 1))
{
g.DrawLine(p, src, dst);
}
using (SolidBrush sb = new SolidBrush(c))
{
if (src.X > dst.X)
{
// left.
dst.X -= (int)(sf.Width + 0.5f);
}
if (src.Y > dst.Y)
{
// upper left.
dst.Y -= (int)(sf.Height + 0.5f);
}
using (SolidBrush sbBack = new SolidBrush(Color.FromArgb(128, Color.Gray)))
{
g.FillRectangle(sbBack, dst.X, dst.Y, (int)sf.Width + 1, (int)sf.Height + 1);
}
g.DrawString(Text, f, sb, dst);
}
}
}
/// <summary>
/// Point constructor.
/// </summary>
/// <param name="text"></param>
/// <param name="p"></param>
public marker(string text, System.Drawing.Point p)
{
IsRect = false;
Location = p;
Text = text;
}
/// <summary>
/// Rectangle constructor.
/// </summary>
/// <param name="text"></param>
/// <param name="r"></param>
public marker(string text, System.Drawing.Rectangle r)
{
IsRect = true;
Rectangle = r;
Text = text;
}
/// <summary>
/// Is rectangle.
/// </summary>
public bool IsRect { get; set; }
/// <summary>
/// Location.
/// </summary>
public System.Drawing.Point Location { get; set; }
/// <summary>
/// Rectangle.
/// </summary>
public System.Drawing.Rectangle Rectangle { get; set; }
/// <summary>
/// Text.
/// </summary>
public string Text { get; set; }
}
}
}