Как создать собственную треугольную аннотацию?
В этом разделе
VintaSoft Annotation .NET Plug-in позволяет создавать пользовательские аннотации с нуля, т.е.:
- Создать класс, который является производным от AnnotationData и хранит информацию о данных аннотации.
- Создать класс, который реализует интерфейс IInteractionController и определяет, как можно построить аннотацию.
- Создать класс, который реализует интерфейс IInteractionController и определяет, как можно преобразовать аннотацию.
- Создать класс, который является производным от InteractionPoint и при необходимости определяет внешний вид интерактивных точек аннотации.
- Создать класс, который является производным от AnnotationView и определяет вид аннотации, а также то, как пользователь может взаимодействовать с аннотацией.
Также плагин позволяет использовать любую стандартную аннотацию в качестве базового класса для пользовательских аннотаций, поскольку архитектура SDK является открытой.
В этой статье описывается, как создать треугольную аннотацию, основанную на полигональной аннотации. Для выполнения задачи необходимо создать 3 класса:
Класс TriangleAnnotationData
Класс TriangleAnnotationData:
- Сохраняет данные аннотации (координаты вершин треугольника) в свойствах класса.
- Сериализует данные аннотации с помощью конструктора сериализации.
- Клонирует данные аннотации, используя метод Clone.
Вот C#/VB.NET код, показывающий реализацию класса TriangleAnnotationData:
using System;
using System.Drawing;
using System.Runtime.Serialization;
using System.Security.Permissions;
using Vintasoft.Imaging.Annotation;
namespace DemosCommonCode.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 DemosCommonCode.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
Класс TriangleAnnotationInteractionPoint мог бы быть не реализован, но мы решили изменить внешний вид вершин треугольника и сделаем это в этом классе.
Класс TriangleAnnotationInteractionPoint:
- Определяет внешний вид вершин треугольника (вершина будет отображаться как большой красный круг) в конструкторе класса.
- Рисует вершину прямоугольника, используя метод Draw.
- Клонирует вершину прямоугольника, используя метод Clone.
Вот C#/VB.NET код, показывающий реализацию класса TriangleAnnotationInteractionPoint:
using System.Drawing;
using Vintasoft.Imaging.UI;
using Vintasoft.Imaging.UI.VisualTools.UserInteraction;
namespace DemosCommonCode.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 DemosCommonCode.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
Класс TriangleAnnotationView:
- Определяет, что для построения аннотации необходимо использовать стандартный трансформер на основе точек и что объект должен содержать 3 точки.
- Определяет, что для преобразования аннотации в прямоугольник необходимо использовать стандартный трансформер на основе прямоугольника.
- Определяет, что для преобразования аннотации в набор точек необходимо использовать стандартный трансформер на основе точек, для рисования вершин следует использовать класс TriangleAnnotationInteractionPoint.
- Клонирует внешний вид аннотации с помощью метода Clone.
Вот C#/VB.NET код, показывающий реализацию класса TriangleAnnotationView:
using System.Drawing;
using Vintasoft.Imaging.Annotation;
using Vintasoft.Imaging.Annotation.UI;
using Vintasoft.Imaging.Annotation.UI.VisualTools.UserInteraction;
namespace DemosCommonCode.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 DemosCommonCode.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
Регистрация связи между классами TriangleAnnotationData и TriangleAnnotationView
Связь между TriangleAnnotationData и Классы TriangleAnnotationView должны быть зарегистрированы до создания любого экземпляра класса TriangleAnnotationView. Связь между классами TriangleAnnotationData и TriangleAnnotationView можно зарегистрировать с помощью метода
AnnotationViewFactory.RegisterViewForAnnotationData.
Примеры
Реализация треугольной аннотации в C# и VB.NET является частью кода проекта AnnotationDemo и WpfAnnotationDemo.