VintaSoft Imaging .NET SDK 15.2: Documentation for .NET developer
In This Topic
How to create custom triangle annotation?
In This Topic
VintaSoft Annotation .NET Plug-in allows to create custom annotation from scratch, i.e.: Also Plug-in allows to use any standard annotation as a base class for custom annotation because SDK provides open architecture.


This article describes how to create triangle annotation, which is based on polygon annotation. For doing the task is necessary to create 3 classes:

TriangleAnnotationData class

TriangleAnnotationData class:
Here is C#/VB.NET code that shows implementation of TriangleAnnotationData class:
using System;
using System.Drawing;
using System.Runtime.Serialization;
using System.Security.Permissions;

using Vintasoft.Imaging.Annotation;

namespace CommonCode.Annotation
{
    /// <summary>
    /// Class that holds information about the annotation that displays a triangle.
    /// </summary>
    [Serializable]
    public class TriangleAnnotationData : PolygonAnnotationData
    {

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="TriangleAnnotationData"/> class.
        /// </summary>
        public TriangleAnnotationData()
            : base()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="TriangleAnnotationData"/> class.
        /// </summary>
        /// <param name="info">The SerializationInfo to populate with data.</param>
        /// <param name="context">The destination for this serialization.</param>
        public TriangleAnnotationData(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
            int sdkVersion = 70;
            if (context.Context is int)
                sdkVersion = (int)context.Context;

            if (sdkVersion < 70)
            {
                try
                {
                    PointF firstPoint = (PointF)info.GetValue("FirstPoint", typeof(PointF));
                    PointF secondPoint = (PointF)info.GetValue("SecondPoint", typeof(PointF));
                    PointF thirdPoint = (PointF)info.GetValue("ThirdPoint", typeof(PointF));

                    PointF[] points = new PointF[] { firstPoint, secondPoint, thirdPoint };

                    this.Points.ClearAndAddRange(points);
                }
                catch
                {
                }

                //
                this.Location = (PointF)info.GetValue("Location", typeof(PointF));

                this.FillBrush = new AnnotationSolidBrush(Color.Transparent);
                this.Border = true;
                this.Outline.DashStyle = AnnotationPenDashStyle.Solid;
            }
        }

        #endregion



        #region Methods

        /// <summary>
        /// Creates a new object that is a copy of the current instance.
        /// </summary>
        /// <returns>A new object that is a copy of this instance.</returns>
        public override object Clone()
        {
            TriangleAnnotationData result = new TriangleAnnotationData();
            CopyTo(result);
            return result;
        }


        #region ISerializable Members

        /// <summary>
        /// Populates a SerializationInfo with the data needed to serialize the target object.
        /// </summary>
        /// <param name="info">The SerializationInfo to populate with data.</param>
        /// <param name="context">The destination for this serialization.</param>
        [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            if (info == null)
                throw new ArgumentNullException("info");

            int sdkVersion = 70;
            if (context.Context is int)
                sdkVersion = (int)context.Context;

            if (sdkVersion >= 70)
            {
                base.GetObjectData(info, context);
            }
            else
            {
                info.AddValue("Guid", this.Guid);
                info.AddValue("CreationTime", this.CreationTime);
                info.AddValue("ModifiedTime", this.ModifiedTime);

                info.AddValue("Location", this.Location);
                info.AddValue("Rotation", this.Rotation);
                info.AddValue("Size", this.Size);
                info.AddValue("Visible", this.IsVisible);
                info.AddValue("HorizontalMirrored", this.HorizontalMirrored);
                info.AddValue("VerticalMirrored", this.VerticalMirrored);

                info.AddValue("Border", this.Border);

                info.AddValue("ZOrder", (int)0);
                info.AddValue("BackColor", Color.Black);

                info.AddValue("Outline", this.Outline);
                info.AddValue("ToolTip", this.ToolTip);

                if (sdkVersion >= 43)
                    info.AddValue("Name", this.Name);

                info.AddValue("FirstPoint", PointF.Empty);
                info.AddValue("SecondPoint", PointF.Empty);
                info.AddValue("ThirdPoint", PointF.Empty);
            }
        }

        #endregion

        #endregion

    }
}
Imports System.Drawing
Imports System.Runtime.Serialization
Imports System.Security.Permissions

Imports Vintasoft.Imaging.Annotation

Namespace CommonCode.Annotation
    ''' <summary>
    ''' Class that holds information about the annotation that displays a triangle.
    ''' </summary>
    <Serializable> _
    Public Class TriangleAnnotationData
        Inherits PolygonAnnotationData

        #Region "Constructors"

        ''' <summary>
        ''' Initializes a new instance of the <see cref="TriangleAnnotationData"/> class.
        ''' </summary>
        Public Sub New()
            MyBase.New()
        End Sub

        ''' <summary>
        ''' Initializes a new instance of the <see cref="TriangleAnnotationData"/> class.
        ''' </summary>
        ''' <param name="info">The SerializationInfo to populate with data.</param>
        ''' <param name="context">The destination for this serialization.</param>
        Public Sub New(info As SerializationInfo, context As StreamingContext)
            MyBase.New(info, context)
            Dim sdkVersion As Integer = 70
            If TypeOf context.Context Is Integer Then
                sdkVersion = CInt(context.Context)
            End If

            If sdkVersion < 70 Then
                Try
                    Dim firstPoint As PointF = CType(info.GetValue("FirstPoint", GetType(PointF)), PointF)
                    Dim secondPoint As PointF = CType(info.GetValue("SecondPoint", GetType(PointF)), PointF)
                    Dim thirdPoint As PointF = CType(info.GetValue("ThirdPoint", GetType(PointF)), PointF)

                    Dim points As PointF() = New PointF() {firstPoint, secondPoint, thirdPoint}

                    Me.Points.ClearAndAddRange(points)
                Catch
                End Try

                '
                Me.Location = CType(info.GetValue("Location", GetType(PointF)), PointF)

                Me.FillBrush = New AnnotationSolidBrush(Color.Transparent)
                Me.Border = True
                Me.Outline.DashStyle = AnnotationPenDashStyle.Solid
            End If
        End Sub

        #End Region



        #Region "Methods"

        ''' <summary>
        ''' Creates a new object that is a copy of the current instance.
        ''' </summary>
        ''' <returns>A new object that is a copy of this instance.</returns>
        Public Overrides Function Clone() As Object
            Dim result As New TriangleAnnotationData()
            CopyTo(result)
            Return result
        End Function


        #Region "ISerializable Members"

        ''' <summary>
        ''' Populates a SerializationInfo with the data needed to serialize the target object.
        ''' </summary>
        ''' <param name="info">The SerializationInfo to populate with data.</param>
        ''' <param name="context">The destination for this serialization.</param>
        <SecurityPermission(SecurityAction.LinkDemand, Flags := SecurityPermissionFlag.SerializationFormatter)> _
        Public Overrides Sub GetObjectData(info As SerializationInfo, context As StreamingContext)
            If info Is Nothing Then
                Throw New ArgumentNullException("info")
            End If

            Dim sdkVersion As Integer = 70
            If TypeOf context.Context Is Integer Then
                sdkVersion = CInt(context.Context)
            End If

            If sdkVersion >= 70 Then
                MyBase.GetObjectData(info, context)
            Else
                info.AddValue("Guid", Me.Guid)
                info.AddValue("CreationTime", Me.CreationTime)
                info.AddValue("ModifiedTime", Me.ModifiedTime)

                info.AddValue("Location", Me.Location)
                info.AddValue("Rotation", Me.Rotation)
                info.AddValue("Size", Me.Size)
                info.AddValue("Visible", Me.IsVisible)
                info.AddValue("HorizontalMirrored", Me.HorizontalMirrored)
                info.AddValue("VerticalMirrored", Me.VerticalMirrored)

                info.AddValue("Border", Me.Border)

                info.AddValue("ZOrder", CInt(0))
                info.AddValue("BackColor", Color.Black)

                info.AddValue("Outline", Me.Outline)
                info.AddValue("ToolTip", Me.ToolTip)

                If sdkVersion >= 43 Then
                    info.AddValue("Name", Me.Name)
                End If

                info.AddValue("FirstPoint", PointF.Empty)
                info.AddValue("SecondPoint", PointF.Empty)
                info.AddValue("ThirdPoint", PointF.Empty)
            End If
        End Sub

        #End Region

        #End Region

    End Class
End Namespace



TriangleAnnotationInteractionPoint class

TriangleAnnotationInteractionPoint class could have been not implemented, but we had decided to change the appearance of triangle vertices and will do this in this class.
TriangleAnnotationInteractionPoint class:
Here is C#/VB.NET code that shows implementation of TriangleAnnotationInteractionPoint class:
using System.Drawing;

using Vintasoft.Imaging.UI;
using Vintasoft.Imaging.UI.VisualTools.UserInteraction;

namespace CommonCode.Annotation
{
    /// <summary>
    /// Represents rounded interaction point for vertices of triangle annotation.
    /// </summary>
    public class TriangleAnnotationInteractionPoint : InteractionPolygonPoint
    {

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="TriangleAnnotationInteractionPoint"/> class.
        /// </summary>
        public TriangleAnnotationInteractionPoint()
            : base("Resize")
        {
            BorderColor = Color.Black;
            FillColor = Color.FromArgb(100, Color.Red);
            Radius = 6;
        }

        #endregion



        #region Methods

        /// <summary>
        /// Draws the interaction area on specified graphics.
        /// </summary>
        /// <param name="viewer">The image viewer.</param>
        /// <param name="g">The graphics to draw the interaction area.</param>
        public override void Draw(ImageViewer viewer, Graphics g)
        {
            RectangleF rect = GetDrawingRect();

            if (FillBrush != null)
                g.FillEllipse(FillBrush, rect);
            if (BorderPen != null)
                g.DrawEllipse(BorderPen, rect);
        }

        /// <summary>
        /// Creates a new object that is a copy of the current instance.
        /// </summary>
        /// <returns>A new object that is a copy of this instance.</returns>
        public override InteractionArea Clone()
        {
            TriangleAnnotationInteractionPoint area = new TriangleAnnotationInteractionPoint();
            CopyTo(area);
            return area;
        }

        #endregion

    }
}

Imports System.Drawing

Imports Vintasoft.Imaging.UI
Imports Vintasoft.Imaging.UI.VisualTools.UserInteraction

Namespace CommonCode.Annotation
    ''' <summary>
    ''' Represents rounded interaction point for vertices of triangle annotation.
    ''' </summary>
    Public Class TriangleAnnotationInteractionPoint
        Inherits InteractionPolygonPoint

        #Region "Constructors"

        ''' <summary>
        ''' Initializes a new instance of the <see cref="TriangleAnnotationInteractionPoint"/> class.
        ''' </summary>
        Public Sub New()
            MyBase.New("Resize")
            BorderColor = Color.Black
            FillColor = Color.FromArgb(100, Color.Red)
            Radius = 6
        End Sub

        #End Region



        #Region "Methods"

        ''' <summary>
        ''' Draws the interaction area on specified graphics.
        ''' </summary>
        ''' <param name="viewer">The image viewer.</param>
        ''' <param name="g">The graphics to draw the interaction area.</param>
        Public Overrides Sub Draw(viewer As ImageViewer, g As Graphics)
            Dim rect As RectangleF = GetDrawingRect()

            If FillBrush IsNot Nothing Then
                g.FillEllipse(FillBrush, rect)
            End If
            If BorderPen IsNot Nothing Then
                g.DrawEllipse(BorderPen, rect)
            End If
        End Sub

        ''' <summary>
        ''' Creates a new object that is a copy of the current instance.
        ''' </summary>
        ''' <returns>A new object that is a copy of this instance.</returns>
        Public Overrides Function Clone() As InteractionArea
            Dim area As New TriangleAnnotationInteractionPoint()
            CopyTo(area)
            Return area
        End Function

        #End Region

    End Class
End Namespace



TriangleAnnotationView class

TriangleAnnotationView class:
Here is C#/VB.NET code that shows implementation of TriangleAnnotationView class:
using System.Drawing;

using Vintasoft.Imaging.Annotation;
using Vintasoft.Imaging.Annotation.UI;
using Vintasoft.Imaging.Annotation.UI.VisualTools.UserInteraction;

namespace CommonCode.Annotation
{
    /// <summary>
    /// Class that determines how to display the annotation that displays a triangle
    /// and how user can interact with annotation.
    /// </summary>
    public class TriangleAnnotationView : PolygonAnnotationView
    {

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="TriangleAnnotationView"/> class.
        /// </summary>
        /// <param name="annotationData">Object that stores the annotation data.</param>
        public TriangleAnnotationView(TriangleAnnotationData annotationData)
            : base(annotationData)
        {
            FillBrush = null;

            // create a point-based builder
            Builder = new PointBasedAnnotationPointBuilder(this, 3, 3);

            // create a transformer for rectangular mode
            PointBasedAnnotationRectangularTransformer rectangleTransformer = new PointBasedAnnotationRectangularTransformer(this);
            // show bounding box area
            rectangleTransformer.BoundingBoxArea.IsVisible = true;
            RectangularTransformer = rectangleTransformer;

            // create a transformer for point mode
            PointBasedAnnotationPointTransformer pointsTransformer = new PointBasedAnnotationPointTransformer(this);
            // change interaction points color
            pointsTransformer.InteractionPointBackColor = Color.FromArgb(100, Color.Red);
            pointsTransformer.SelectedInteractionPointBackColor = Color.FromArgb(150, Color.Red);
            // change interaction points type
            pointsTransformer.PolygonPointTemplate = new TriangleAnnotationInteractionPoint();
            PointTransformer = pointsTransformer;

            GripMode = GripMode.RectangularAndPoints;                
        }

        #endregion



        #region Methods

        /// <summary>
        /// Creates a new object that is a copy of the current
        /// <see cref="TriangleAnnotationView"/> instance.
        /// </summary>
        /// <returns>A new object that is a copy of this <see cref="TriangleAnnotationView"/>
        /// instance.</returns>
        public override object Clone()
        {
            return new TriangleAnnotationView((TriangleAnnotationData)this.Data.Clone());
        }

        #endregion

    }
}

Imports System.Drawing

Imports Vintasoft.Imaging.Annotation
Imports Vintasoft.Imaging.Annotation.UI
Imports Vintasoft.Imaging.Annotation.UI.VisualTools.UserInteraction

Namespace CommonCode.Annotation
    ''' <summary>
    ''' Class that determines how to display the annotation that displays a triangle
    ''' and how user can interact with annotation.
    ''' </summary>
    Public Class TriangleAnnotationView
        Inherits PolygonAnnotationView

        #Region "Constructors"

        ''' <summary>
        ''' Initializes a new instance of the <see cref="TriangleAnnotationView"/> class.
        ''' </summary>
        ''' <param name="annotationData">Object that stores the annotation data.</param>
        Public Sub New(annotationData As TriangleAnnotationData)
            MyBase.New(annotationData)
            FillBrush = Nothing

            ' create a point-based builder
            Builder = New PointBasedAnnotationPointBuilder(Me, 3, 3)

            ' create a transformer for rectangular mode
            Dim rectangleTransformer As New PointBasedAnnotationRectangularTransformer(Me)
            ' show bounding box area
            rectangleTransformer.BoundingBoxArea.IsVisible = True
            RectangularTransformer = rectangleTransformer

            ' create a transformer for point mode
            Dim pointsTransformer As New PointBasedAnnotationPointTransformer(Me)
            ' change interaction points color
            pointsTransformer.InteractionPointBackColor = Color.FromArgb(100, Color.Red)
            pointsTransformer.SelectedInteractionPointBackColor = Color.FromArgb(150, Color.Red)
            ' change interaction points type
            pointsTransformer.PolygonPointTemplate = New TriangleAnnotationInteractionPoint()
            PointTransformer = pointsTransformer

            GripMode = GripMode.RectangularAndPoints
        End Sub

        #End Region



        #Region "Methods"

        ''' <summary>
        ''' Creates a new object that is a copy of the current
        ''' <see cref="TriangleAnnotationView"/> instance.
        ''' </summary>
        ''' <returns>A new object that is a copy of this <see cref="TriangleAnnotationView"/>
        ''' instance.</returns>
        Public Overrides Function Clone() As Object
            Return New TriangleAnnotationView(DirectCast(Me.Data.Clone(), TriangleAnnotationData))
        End Function

        #End Region

    End Class
End Namespace



Register link between TriangleAnnotationData and TriangleAnnotationView classes

Link between TriangleAnnotationData and TriangleAnnotationView classes should be registered before any instance of TriangleAnnotationView class will be created. Link between TriangleAnnotationData and TriangleAnnotationView classes can be registered using the AnnotationViewFactory.RegisterViewForAnnotationData method.


Examples

The implementation of triangle annotation in C# and VB.NET is a part of AnnotationDemo and WpfAnnotationDemo project code.