VintaSoft Imaging .NET SDK 12.4: Documentation for .NET developer
In This Topic
    Annotation data
    In This Topic
    The AnnotationData class is intended for storing the base information about annotation.
    The complete information about annotation is stored in a class derived from AnnotationData class.

    Annotations, derived from AnnotationData class, are divided into 3 types:


    Annotation location

    The AnnotationData.Location property allows to get/set the annotation location.

    Location of rectangle-based annotation always matches with center of annotation's rectangle.
    Location of points-based annotation by default matches with its first point, unless the coordinates of the first point are changed.

    Location is specified and stored in the image coordinate system with the beginning in the left upper corner. Unit of measure is 1 DIP (Device Independent Pixel) which equal 1/96 inch.


    Annotation size

    The AnnotationData.Size property allows to get/set the annotation size.

    Size is specified and stored in the image coordinate system with the beginning in the left upper corner. Unit of measure is 1 DIP (Device Independent Pixel) which equal 1/96 inch.


    Annotation rotation angle and center of rotation

    The AnnotationData.Rotation property allows to get/set the annotation rotation in degrees.

    Rotation center of annotation is the point in the image coordinate system, in regard to which the annotation is rotated when value of AnnotationData.Rotation property is changed.
    The rotation center of any annotation can be calculated as follows:

    Annotation's rotation angle is the deviation angle from normal non-rotated state of annotation. It is specified and stored in degrees. Rotation angle has positive value when annotation is rotating clockwise and negative when counterclockwise.


    Annotation bounding rectangle

    The bounding rectangle of annotation is the minimum rectangle, which includes the annotation in whole and which sides are parallels to the image sides.
    For rectangle-based annotation the bounding rectangle is the minimum rectangle, which includes all vertices of annotation's rectangle and its center always matches with center of annotation's rectangle.
    For points-based annotation the bounding rectangle is the minimum rectangle, which includes all annotation's points.

    AnnotationData.GetBoundingBox method calculates a bounding box of annotation.
    Here is C#/VB.NET code that shows how to check if the annotation is inside the image boundaries:
    bool IsAnnotationInsideImage(
        Vintasoft.Imaging.Annotation.AnnotationData annotation, 
        Vintasoft.Imaging.VintasoftImage image)
    {
        // get the bounding box
        System.Drawing.RectangleF boundingBox = annotation.GetBoundingBox();
        // calculate image size in device independent pixels
        float imageWidthInDips = image.Width * 96f / (float)image.Resolution.Horizontal;
        float imageHeightInDips = image.Height * 96f / (float)image.Resolution.Vertical;
        System.Drawing.RectangleF imageRect = 
            new System.Drawing.RectangleF(0, 0, imageWidthInDips, imageHeightInDips);
        // check if image rectangle contains the bounding box
        return imageRect.Contains(boundingBox);
    }
    
    Private Function IsAnnotationInsideImage(annotation As Vintasoft.Imaging.Annotation.AnnotationData, image As Vintasoft.Imaging.VintasoftImage) As Boolean
        ' get the bounding box
        Dim boundingBox As System.Drawing.RectangleF = annotation.GetBoundingBox()
        ' calculate image size in device independent pixels
        Dim imageWidthInDips As Single = image.Width * 96F / CSng(image.Resolution.Horizontal)
        Dim imageHeightInDips As Single = image.Height * 96F / CSng(image.Resolution.Vertical)
        Dim imageRect As New System.Drawing.RectangleF(0, 0, imageWidthInDips, imageHeightInDips)
        ' check if image rectangle contains the bounding box
        Return imageRect.Contains(boundingBox)
    End Function
    

    AnnotationData.GetBoundingBox(PointF location, SizeF size, float rotation) method calculates the bounding box that annotation would have with location, size and rotation parameters passed as arguments of method.
    Here is C#/VB.NET code that shows how to restrict the rotation angle of annotation to prevent it from overrunning the boundaries of the specified area:
    System.Drawing.RectangleF _boundingArea;
    Vintasoft.Imaging.Annotation.AnnotationData _annotation;
    
    void SubscribeOnPropertyChanging()
    {
        _annotation.PropertyChanging += 
            new System.EventHandler<Vintasoft.Imaging.ObjectPropertyChangingEventArgs>(annotation_PropertyChanging);
    }
    
    void annotation_PropertyChanging(object sender, Vintasoft.Imaging.ObjectPropertyChangingEventArgs e)
    {
        if (e.PropertyName == "Rotation")
        {
            System.Drawing.RectangleF boundingBox = _annotation.GetBoundingBox(
                _annotation.Location, _annotation.Size, (float)e.NewValue);
    
            if (!_boundingArea.Contains(boundingBox))
            {
                e.Cancel = true;
            }
        }
    }
    
    Private _boundingArea As System.Drawing.RectangleF
    Private _annotation As Vintasoft.Imaging.Annotation.AnnotationData
    
    Private Sub SubscribeOnPropertyChanging()
        AddHandler _annotation.PropertyChanging, New System.EventHandler(Of Vintasoft.Imaging.ObjectPropertyChangingEventArgs)(AddressOf annotation_PropertyChanging)
    End Sub
    
    Private Sub annotation_PropertyChanging(sender As Object, e As Vintasoft.Imaging.ObjectPropertyChangingEventArgs)
        If e.PropertyName = "Rotation" Then
            Dim boundingBox As System.Drawing.RectangleF = _annotation.GetBoundingBox(_annotation.Location, _annotation.Size, CSng(e.NewValue))
    
            If Not _boundingArea.Contains(boundingBox) Then
                e.Cancel = True
            End If
        End If
    End Sub
    


    Annotation properties

    AnnotationData class contains a set of properties divided into following groups:
    Classes, which are derived from AnnotationData class, have additional properties, which specify annotation data. For example, the LineAnnotationDataBase class has Points property, which contains information about points of annotation.


    Add comments to the annotation

    Each annotation can be commented. The AnnotationData.Comment property returns the root comment for annotation (an instance of AnnotationComment class). The AnnotationComment.Replies property returns the comment collection (an instance of CommentCollection class), which contains replies to the comment.


    Monitor changes in annotation properties

    The AnnotationData class provides events, which allow to monitor changes in annotation properties:


    Load and save annotation

    AnnotationData class implements ISerializable interface. This allows to load/save annotations using any formatter, which implements IFormatter interface.


    Initialize the annotation properties

    The AnnotationData class implements ISupportInitialize interface.

    The AnnotationData.BeginInit method allows to start initialization of annotation properties. The AnnotationData.BeginInit raises the AnnotationData.PropertyChanged event with the following properties: PropertyName="IsInitializing", NewValue=True.

    The AnnotationData.EndInit method allows to stop initialization of annotation properties. The AnnotationData.BeginInit raises the AnnotationData.PropertyChanged event with the following properties: PropertyName="IsInitializing", NewValue=False.

    The AnnotationData.BeginInit and AnnotationData.EndInit methods just generate additional AnnotationData.PropertyChanged events and does not change logic of calling AnnotationData.PropertyChanging and AnnotationData.PropertyChanged events of annotation.
    The AnnotationData.BeginInit and AnnotationData.EndInit methods can be nested.


    Clone annotation

    The AnnotationData class implements ICloneable interface.

    Here is C#/VB.NET code that shows how to clone single annotation from a collection and add cloned annotation into the same collection:
    void CloneAndAdd(Vintasoft.Imaging.Annotation.AnnotationDataCollection annotationCollection, int index)
    {
        // clone annotation at specified index
        Vintasoft.Imaging.Annotation.AnnotationData clonedAnnotation = 
            (Vintasoft.Imaging.Annotation.AnnotationData)annotationCollection[index].Clone();
        // add cloned annotation to the end of the collection
        annotationCollection.Add(clonedAnnotation);
    }
    
    Private Sub CloneAndAdd(annotationCollection As Vintasoft.Imaging.Annotation.AnnotationDataCollection, index As Integer)
        ' clone annotation at specified index
        Dim clonedAnnotation As Vintasoft.Imaging.Annotation.AnnotationData = DirectCast(annotationCollection(index).Clone(), Vintasoft.Imaging.Annotation.AnnotationData)
        ' add cloned annotation to the end of the collection
        annotationCollection.Add(clonedAnnotation)
    End Sub
    


    Annotation collection

    The AnnotationDataCollection class is a collection of instances of AnnotationData class. The AnnotationDataCollection class provides the ability to add, remove, rearrange, sort elements, convert AnnotationData elements to array, subscribe to property changing/change events of each annotation.