VintaSoft Imaging .NET SDK 15.2: Документация для .NET разработчика
В этом разделе
Визуальный инструмент WpfGraphicObjectTool.
В этом разделе
Визуальный инструмент WpfGraphicObjectTool позволяет отображать статические графические объекты в WpfImageViewer.


Графический объект

Класс WpfGraphicObject является базовым классом для статических объектов и позволяет: Вот список стандартных статических объектов: Вот C#/VB.NET код, который демонстрирует, как отобразить сетку над изображением:
/// <summary>
/// Displays grid over image in image viewer.
/// </summary>
/// <param name="viewer">The viewer.</param>
public static void SetGridGraphicObject(Vintasoft.Imaging.Wpf.UI.WpfImageViewer viewer)
{
    // create visual tool that can display static graphic objects in an image viewer
    Vintasoft.Imaging.Wpf.UI.VisualTools.GraphicObjects.WpfGraphicObjectTool tool =
        new Vintasoft.Imaging.Wpf.UI.VisualTools.GraphicObjects.WpfGraphicObjectTool();
    // create graphic object that displays image grid
    WpfGridGraphicObject grid = new WpfGridGraphicObject(tool);
    // add graphic object to the visual tool
    tool.GraphicObjectCollection.Add(grid);
    // set visual tool as current visual tool of image viewer
    viewer.VisualTool = tool;
}


/// <summary>
/// Represents an image grid which can be displayed in WPF image viewer.
/// </summary>
public class WpfGridGraphicObject : Vintasoft.Imaging.Wpf.UI.VisualTools.GraphicObjects.WpfGraphicObject
{

    #region Fields

    Vintasoft.Imaging.Wpf.UI.VisualTools.WpfVisualTool _tool;

    #endregion



    #region Constructors

    /// <summary>
    /// Initializes a new instance of the <see cref="WpfGridGraphicObject"/> class.
    /// </summary>
    /// <param name="tool">The visual tool.</param>
    public WpfGridGraphicObject(Vintasoft.Imaging.Wpf.UI.VisualTools.WpfVisualTool tool)
    {
        if (tool == null)
            throw new System.ArgumentNullException();
        _tool = tool;
        Pen = new System.Windows.Media.Pen(
            new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromArgb(128, 0, 255, 0)), 1);
        PointTransform = new Vintasoft.Imaging.Wpf.UI.VisualTools.WpfPixelsToImageViewerPointTransform();
    }

    #endregion



    #region Properties

    System.Windows.Point _location = new System.Windows.Point(0, 0);
    /// <summary>
    /// Gets or sets the location of grid.
    /// </summary>
    /// <value>
    /// Default value is <b>(0,0)</b>.
    /// </value>
    public System.Windows.Point Location
    {
        get
        {
            return _location;
        }
        set
        {
            _location = value;
        }
    }

    System.Windows.Size _cellSize = new System.Windows.Size(1, 1);
    /// <summary>
    /// Gets or sets the size of the grid cell.
    /// </summary>
    /// <value>
    /// Default value is <b>(1,1)</b>.
    /// </value>
    public System.Windows.Size CellSize
    {
        get
        {
            return _cellSize;
        }
        set
        {
            _cellSize = value;
        }
    }

    Vintasoft.Imaging.UnitOfMeasure _cellUnitOfMeasure =
        Vintasoft.Imaging.UnitOfMeasure.Centimeters;
    /// <summary>
    /// Gets or sets the unit of measure of the grid cell.
    /// </summary>
    /// <value>
    /// Default value is <b>UnitOfMeasure.Centimeters</b>.
    /// </value>
    public Vintasoft.Imaging.UnitOfMeasure CellUnitOfMeasure
    {
        get
        {
            return _cellUnitOfMeasure;
        }
        set
        {
            _cellUnitOfMeasure = value;
        }
    }

    #endregion



    #region Methods

    /// <summary>
    /// Returns a value indicating whether point belongs the object.
    /// </summary>
    /// <param name="p">Point in object space.</param>
    /// <param name="ignoreContainmentCheckDistance">A value indicating whether the point must be checked on the object only (ignore
    /// the "containment" region around object that is used for object selection).</param>
    /// <returns>
    /// <b>true</b> if point belongs the object;
    /// otherwise, <b>false</b>.
    /// </returns>
    public override bool IsPointOnObject(System.Windows.Point p, bool ignoreContainmentCheckDistance)
    {
        if (_tool.ImageViewer.Image != null &&
            (Pen != null || Brush != null))
        {
            System.Windows.Rect rect = GetRectangle(_location, _tool.ImageViewer.Image);
            return rect.Contains(p);
        }
        else
            return false;
    }

    /// <summary>
    /// Returns a bounding box of object, in object space.
    /// </summary>
    /// <returns>
    /// Bounding box of object, in object space.
    /// </returns>
    public override System.Windows.Rect GetBoundingBox()
    {
        if (_tool.ImageViewer.Image != null)
            return GetRectangle(_location, _tool.ImageViewer.Image);
        else
            return System.Windows.Rect.Empty;
    }

    /// <summary>
    /// Renders the object on specified <see cref="T:System.Windows.Media.DrawingContext" />
    /// in the object space.
    /// </summary>
    /// <param name="viewer">An image viewer.</param>
    /// <param name="context">A drawing context where the object must be rendered.</param>
    /// <remarks>
    /// This method draws object after
    /// the <see cref="P:Vintasoft.Imaging.Wpf.UI.VisualTools.GraphicObjects.WpfGraphicObject.PointTransform" />
    /// is applied to the DrawingContext, specified by <i>context</i> parameter.<br /><br />
    /// By default this method does not do anything.
    /// </remarks>
    public override void RenderInObjectSpace(
        Vintasoft.Imaging.Wpf.UI.WpfImageViewer viewer, System.Windows.Media.DrawingContext context)
    {
        if (viewer.Image == null)
            return;

        System.Windows.Rect rect = GetRectangle(_location, viewer.Image);
        context.DrawRectangle(Brush, null, rect);

        if (Pen != null && !CellSize.IsEmpty)
        {
            double cellHeight = Vintasoft.Imaging.Utils.UnitOfMeasureConverter.ConvertToPixels(
                CellSize.Height, CellUnitOfMeasure);
            int countRow = (int)System.Math.Ceiling(rect.Height / cellHeight);

            double cellWidth = Vintasoft.Imaging.Utils.UnitOfMeasureConverter.ConvertToPixels(
                CellSize.Width, CellUnitOfMeasure);
            int countColumn = (int)System.Math.Ceiling(rect.Width / cellWidth);

            if (countRow > 0 && countColumn > 0)
            {
                double x1 = rect.X;
                double y1 = rect.Y + cellHeight;
                double x2 = rect.Right;
                int i;
                for (i = 1; i < countRow; i++, y1 += cellHeight)
                    context.DrawLine(Pen, new System.Windows.Point(x1, y1), new System.Windows.Point(x2, y1));

                x1 += cellWidth;
                y1 = rect.Y;
                double y2 = rect.Bottom;
                for (i = 1; i < countColumn; i++, x1 += cellWidth)
                    context.DrawLine(Pen, new System.Windows.Point(x1, y1), new System.Windows.Point(x1, y2));
            }
        }
    }

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

    /// <summary>
    /// Copies current <see cref="WpfGridGraphicObject"/> to
    /// the target <see cref="WpfGridGraphicObject"/>
    /// </summary>
    /// <param name="obj"><see cref="WpfGridGraphicObject"/> to copy.</param>
    public override void CopyTo(Vintasoft.Imaging.Wpf.UI.VisualTools.GraphicObjects.WpfGraphicObject obj)
    {
        base.CopyTo(obj);

        WpfGridGraphicObject gridObj = obj as WpfGridGraphicObject;
        if (gridObj != null)
        {
            gridObj.Location = Location;
            gridObj.CellSize = CellSize;
            gridObj.CellUnitOfMeasure = CellUnitOfMeasure;
        }
    }

    /// <summary>
    /// Gets the rectangle of grid.
    /// </summary>
    /// <param name="location">The location.</param>
    /// <param name="image">The image.</param>
    private System.Windows.Rect GetRectangle(System.Windows.Point location, Vintasoft.Imaging.VintasoftImage image)
    {
        System.Windows.Rect rect = new System.Windows.Rect(
            _location.X, _location.Y,
            image.Width - _location.X, image.Height - _location.Y);
        return rect;
    }

    #endregion

}
''' <summary>
''' Displays grid over image in image viewer.
''' </summary>
''' <param name="viewer">The viewer.</param>
Public Shared Sub SetGridGraphicObject(viewer As Vintasoft.Imaging.Wpf.UI.WpfImageViewer)
    ' create visual tool that can display static graphic objects in an image viewer
    Dim tool As New Vintasoft.Imaging.Wpf.UI.VisualTools.GraphicObjects.WpfGraphicObjectTool()
    ' create graphic object that displays image grid
    Dim grid As New WpfGridGraphicObject(tool)
    ' add graphic object to the visual tool
    tool.GraphicObjectCollection.Add(grid)
    ' set visual tool as current visual tool of image viewer
    viewer.VisualTool = tool
End Sub


''' <summary>
''' Represents an image grid which can be displayed in WPF image viewer.
''' </summary>
Public Class WpfGridGraphicObject
    Inherits Vintasoft.Imaging.Wpf.UI.VisualTools.GraphicObjects.WpfGraphicObject

    #Region "Fields"

    Private _tool As Vintasoft.Imaging.Wpf.UI.VisualTools.WpfVisualTool

    #End Region



    #Region "Constructors"

    ''' <summary>
    ''' Initializes a new instance of the <see cref="WpfGridGraphicObject"/> class.
    ''' </summary>
    ''' <param name="tool">The visual tool.</param>
    Public Sub New(tool As Vintasoft.Imaging.Wpf.UI.VisualTools.WpfVisualTool)
        If tool Is Nothing Then
            Throw New System.ArgumentNullException()
        End If
        _tool = tool
        Pen = New System.Windows.Media.Pen(New System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromArgb(128, 0, 255, 0)), 1)
        PointTransform = New Vintasoft.Imaging.Wpf.UI.VisualTools.WpfPixelsToImageViewerPointTransform()
    End Sub

    #End Region



    #Region "Properties"

    Private _location As New System.Windows.Point(0, 0)
    ''' <summary>
    ''' Gets or sets the location of grid.
    ''' </summary>
    ''' <value>
    ''' Default value is <b>(0,0)</b>.
    ''' </value>
    Public Property Location() As System.Windows.Point
        Get
            Return _location
        End Get
        Set
            _location = value
        End Set
    End Property

    Private _cellSize As New System.Windows.Size(1, 1)
    ''' <summary>
    ''' Gets or sets the size of the grid cell.
    ''' </summary>
    ''' <value>
    ''' Default value is <b>(1,1)</b>.
    ''' </value>
    Public Property CellSize() As System.Windows.Size
        Get
            Return _cellSize
        End Get
        Set
            _cellSize = value
        End Set
    End Property

    Private _cellUnitOfMeasure As Vintasoft.Imaging.UnitOfMeasure = Vintasoft.Imaging.UnitOfMeasure.Centimeters
    ''' <summary>
    ''' Gets or sets the unit of measure of the grid cell.
    ''' </summary>
    ''' <value>
    ''' Default value is <b>UnitOfMeasure.Centimeters</b>.
    ''' </value>
    Public Property CellUnitOfMeasure() As Vintasoft.Imaging.UnitOfMeasure
        Get
            Return _cellUnitOfMeasure
        End Get
        Set
            _cellUnitOfMeasure = value
        End Set
    End Property

    #End Region



    #Region "Methods"

    ''' <summary>
    ''' Returns a value indicating whether point belongs the object.
    ''' </summary>
    ''' <param name="p">Point in object space.</param>
    ''' <param name="ignoreContainmentCheckDistance">A value indicating whether the point must be checked on the object only (ignore
    ''' the "containment" region around object that is used for object selection).</param>
    ''' <returns>
    ''' <b>true</b> if point belongs the object;
    ''' otherwise, <b>false</b>.
    ''' </returns>
    Public Overrides Function IsPointOnObject(p As System.Windows.Point, ignoreContainmentCheckDistance As Boolean) As Boolean
        If _tool.ImageViewer.Image IsNot Nothing AndAlso (Pen IsNot Nothing OrElse Brush IsNot Nothing) Then
            Dim rect As System.Windows.Rect = GetRectangle(_location, _tool.ImageViewer.Image)
            Return rect.Contains(p)
        Else
            Return False
        End If
    End Function

    ''' <summary>
    ''' Returns a bounding box of object, in object space.
    ''' </summary>
    ''' <returns>
    ''' Bounding box of object, in object space.
    ''' </returns>
    Public Overrides Function GetBoundingBox() As System.Windows.Rect
        If _tool.ImageViewer.Image IsNot Nothing Then
            Return GetRectangle(_location, _tool.ImageViewer.Image)
        Else
            Return System.Windows.Rect.Empty
        End If
    End Function

    ''' <summary>
    ''' Renders the object on specified <see cref="T:System.Windows.Media.DrawingContext" />
    ''' in the object space.
    ''' </summary>
    ''' <param name="viewer">An image viewer.</param>
    ''' <param name="context">A drawing context where the object must be rendered.</param>
    ''' <remarks>
    ''' This method draws object after
    ''' the <see cref="P:Vintasoft.Imaging.Wpf.UI.VisualTools.GraphicObjects.WpfGraphicObject.PointTransform" />
    ''' is applied to the DrawingContext, specified by <i>context</i> parameter.<br /><br />
    ''' By default this method does not do anything.
    ''' </remarks>
    Public Overrides Sub RenderInObjectSpace(viewer As Vintasoft.Imaging.Wpf.UI.WpfImageViewer, context As System.Windows.Media.DrawingContext)
        If viewer.Image Is Nothing Then
            Return
        End If

        Dim rect As System.Windows.Rect = GetRectangle(_location, viewer.Image)
        context.DrawRectangle(Brush, Nothing, rect)

        If Pen IsNot Nothing AndAlso Not CellSize.IsEmpty Then
            Dim cellHeight As Double = Vintasoft.Imaging.Utils.UnitOfMeasureConverter.ConvertToPixels(CellSize.Height, CellUnitOfMeasure)
            Dim countRow As Integer = CInt(Math.Truncate(System.Math.Ceiling(rect.Height / cellHeight)))

            Dim cellWidth As Double = Vintasoft.Imaging.Utils.UnitOfMeasureConverter.ConvertToPixels(CellSize.Width, CellUnitOfMeasure)
            Dim countColumn As Integer = CInt(Math.Truncate(System.Math.Ceiling(rect.Width / cellWidth)))

            If countRow > 0 AndAlso countColumn > 0 Then
                Dim x1 As Double = rect.X
                Dim y1 As Double = rect.Y + cellHeight
                Dim x2 As Double = rect.Right
                Dim i As Integer
                i = 1
                While i < countRow
                    context.DrawLine(Pen, New System.Windows.Point(x1, y1), New System.Windows.Point(x2, y1))
                    i += 1
                    y1 += cellHeight
                End While

                x1 += cellWidth
                y1 = rect.Y
                Dim y2 As Double = rect.Bottom
                i = 1
                While i < countColumn
                    context.DrawLine(Pen, New System.Windows.Point(x1, y1), New System.Windows.Point(x1, y2))
                    i += 1
                    x1 += cellWidth
                End While
            End If
        End If
    End Sub

    ''' <summary>
    ''' Creates a new <see cref="WpfGridGraphicObject"/> that is a copy of the current instance.
    ''' </summary>
    ''' <returns>
    ''' A new <see cref="WpfGridGraphicObject"/> that is a copy of this instance.
    ''' </returns>
    Public Overrides Function Clone() As Object
        Dim obj As New WpfGridGraphicObject(_tool)
        CopyTo(obj)
        Return obj
    End Function

    ''' <summary>
    ''' Copies current <see cref="WpfGridGraphicObject"/> to
    ''' the target <see cref="WpfGridGraphicObject"/>
    ''' </summary>
    ''' <param name="obj"><see cref="WpfGridGraphicObject"/> to copy.</param>
    Public Overrides Sub CopyTo(obj As Vintasoft.Imaging.Wpf.UI.VisualTools.GraphicObjects.WpfGraphicObject)
        MyBase.CopyTo(obj)

        Dim gridObj As WpfGridGraphicObject = TryCast(obj, WpfGridGraphicObject)
        If gridObj IsNot Nothing Then
            gridObj.Location = Location
            gridObj.CellSize = CellSize
            gridObj.CellUnitOfMeasure = CellUnitOfMeasure
        End If
    End Sub

    ''' <summary>
    ''' Gets the rectangle of grid.
    ''' </summary>
    ''' <param name="location">The location.</param>
    ''' <param name="image">The image.</param>
    Private Function GetRectangle(location As System.Windows.Point, image As Vintasoft.Imaging.VintasoftImage) As System.Windows.Rect
        Dim rect As New System.Windows.Rect(_location.X, _location.Y, image.Width - _location.X, image.Height - _location.Y)
        Return rect
    End Function

    #End Region

End Class



Создание внешнего вида объекта

VintaSoft Imaging .NET SDK позволяет создать собственный статический объект с нуля или изменить существующий стандартный статический объект.

Внешний вид объекта можно создать переопределив один из следующих методов: Вот C#/VB.NET код, который демонстрирует, как отобразить повернутый текст путем переопределения метода WpfGraphicObject.RenderInObjectSpace:
/// <summary>
/// Represents a static rotated text which can be displayed in image viewer.
/// </summary>
class WpfRotatedTextGraphicObject : Vintasoft.Imaging.Wpf.UI.VisualTools.GraphicObjects.WpfTextGraphicObject
{

    #region Properties

    double _textRotationAngle = 0.0;
    /// <summary>
    /// Gets or sets the rotation angle, in degrees, of text.
    /// </summary>
    /// <value>
    /// Default value is <b>0.0</b>.
    /// </value>
    public double TextRotationAngle
    {
        get
        {
            return _textRotationAngle;
        }
        set
        {
            _textRotationAngle = value % 360.0;
        }
    }

    #endregion



    #region Methods

    /// <summary>
    /// Renders the object on specified <see cref="System.Windows.Media.DrawingContext" />.
    /// </summary>
    /// <param name="viewer">An image viewer.</param>
    /// <param name="context">A drawing context where the object must be rendered.</param>
    /// <remarks>
    /// This method draws object after the <see cref="Vintasoft.Imaging.Wpf.UI.VisualTools.GraphicObjects.WpfGraphicObject.PointTransform" />
    /// is applied tothe DrawingContext, specified by <i>context</i> parameter.
    /// </remarks>
    public override void RenderInObjectSpace(
        Vintasoft.Imaging.Wpf.UI.WpfImageViewer viewer, System.Windows.Media.DrawingContext context)
    {
        double centerX = Rectangle.X + Rectangle.Width / 2.0;
        double centerY = Rectangle.Y + Rectangle.Height / 2.0;
        context.PushTransform(new System.Windows.Media.RotateTransform(_textRotationAngle, centerX, centerY));

        base.RenderInObjectSpace(viewer, context);

        context.Pop();
    }

    #endregion

}
''' <summary>
''' Represents a static rotated text which can be displayed in image viewer.
''' </summary>
Private Class WpfRotatedTextGraphicObject
    Inherits Vintasoft.Imaging.Wpf.UI.VisualTools.GraphicObjects.WpfTextGraphicObject

    #Region "Properties"

    Private _textRotationAngle As Double = 0.0
    ''' <summary>
    ''' Gets or sets the rotation angle, in degrees, of text.
    ''' </summary>
    ''' <value>
    ''' Default value is <b>0.0</b>.
    ''' </value>
    Public Property TextRotationAngle() As Double
        Get
            Return _textRotationAngle
        End Get
        Set
            _textRotationAngle = value Mod 360.0
        End Set
    End Property

    #End Region



    #Region "Methods"

    ''' <summary>
    ''' Renders the object on specified <see cref="System.Windows.Media.DrawingContext" />.
    ''' </summary>
    ''' <param name="viewer">An image viewer.</param>
    ''' <param name="context">A drawing context where the object must be rendered.</param>
    ''' <remarks>
    ''' This method draws object after the <see cref="Vintasoft.Imaging.Wpf.UI.VisualTools.GraphicObjects.WpfGraphicObject.PointTransform" />
    ''' is applied tothe DrawingContext, specified by <i>context</i> parameter.
    ''' </remarks>
    Public Overrides Sub RenderInObjectSpace(viewer As Vintasoft.Imaging.Wpf.UI.WpfImageViewer, context As System.Windows.Media.DrawingContext)
        Dim centerX As Double = Rectangle.X + Rectangle.Width / 2.0
        Dim centerY As Double = Rectangle.Y + Rectangle.Height / 2.0
        context.PushTransform(New System.Windows.Media.RotateTransform(_textRotationAngle, centerX, centerY))

        MyBase.RenderInObjectSpace(viewer, context)

        context.Pop()
    End Sub

    #End Region

End Class



Вот C#/VB.NET код, который демонстрирует, как отобразить имя загруженного файла, текущий уровень масштабирования и ограничивающий прямоугольник изображения в просмотрщике изображений. Объекты, отвечающие за отображение имени загруженного файла и уровня масштабирования, расположены в координатном пространстве просмотрщика, а объект, отвечающий за отображение ограничивающего прямоугольника, находится в координатном пространстве изображения.
/// <summary>
/// Visual tool that draws static text (filename, current zoom factor) over image in
/// image viewer and draws a frame around image in image viewer:
/// </summary>
class WpfGraphicObjectToolExample : Vintasoft.Imaging.Wpf.UI.VisualTools.GraphicObjects.WpfGraphicObjectTool
{

    #region Fields

    /// <summary>
    /// The graphic object that draws a filename over the image in image viewer.
    /// </summary>
    Vintasoft.Imaging.Wpf.UI.VisualTools.GraphicObjects.WpfTextGraphicObject _fileNameGraphicObject =
        new Vintasoft.Imaging.Wpf.UI.VisualTools.GraphicObjects.WpfTextGraphicObject();

    /// <summary>
    /// The font size of filename.
    /// </summary>
    double _fileNameEmSize = 24;

    /// <summary>
    /// The brush that should be used for drawing text of filename.
    /// </summary>
    System.Windows.Media.Brush _fileNameForeground = System.Windows.Media.Brushes.Salmon;

    /// <summary>
    /// The anchor of text of filename.
    /// </summary>
    Vintasoft.Imaging.AnchorType _fileNameTextAnchor = Vintasoft.Imaging.AnchorType.Top;

    /// <summary>
    /// The graphic object that draws image zoom factor over the image in image viewer.
    /// </summary>
    Vintasoft.Imaging.Wpf.UI.VisualTools.GraphicObjects.WpfTextGraphicObject _zoomGraphicObject =
        new Vintasoft.Imaging.Wpf.UI.VisualTools.GraphicObjects.WpfTextGraphicObject();

    /// <summary>
    /// The font size of zoom.
    /// </summary>
    double _zoomEmSize = 20;

    /// <summary>
    /// The brush of text of zoom.
    /// </summary>
    System.Windows.Media.Brush _zoomForeground = System.Windows.Media.Brushes.Lime;

    /// <summary>
    /// The anchor of text of zoom.
    /// </summary>
    Vintasoft.Imaging.AnchorType _zoomTextAnchor =
        Vintasoft.Imaging.AnchorType.Bottom |
        Vintasoft.Imaging.AnchorType.Right;

    /// <summary>
    /// The graphic object that draws a frame around image in image viewer.
    /// </summary>
    Vintasoft.Imaging.Wpf.UI.VisualTools.GraphicObjects.WpfRectangularGraphicObject _borderGraphicObject =
        new Vintasoft.Imaging.Wpf.UI.VisualTools.GraphicObjects.WpfRectangularGraphicObject();

    /// <summary>
    /// The typeface of text.
    /// </summary>
    System.Windows.Media.Typeface _typeface = new System.Windows.Media.Typeface("Arial");

    #endregion



    #region Constructors

    /// <summary>
    /// Initializes a new instance of the <see cref="WpfGraphicObjectToolExample"/> class.
    /// </summary>
    public WpfGraphicObjectToolExample()
    {
        _fileNameGraphicObject.Typeface = _typeface;
        _fileNameGraphicObject.EmSize = _fileNameEmSize;
        _fileNameGraphicObject.FontBrush = _fileNameForeground;
        _fileNameGraphicObject.TextAnchor = _fileNameTextAnchor;
        GraphicObjectCollection.Add(_fileNameGraphicObject);

        _zoomGraphicObject.Typeface = _typeface;
        _zoomGraphicObject.EmSize = _zoomEmSize;
        _zoomGraphicObject.FontBrush = _zoomForeground;
        _zoomGraphicObject.TextAnchor = _zoomTextAnchor;
        GraphicObjectCollection.Add(_zoomGraphicObject);

        _borderGraphicObject.PointTransform =
            new Vintasoft.Imaging.Wpf.UI.VisualTools.WpfPixelsToImageViewerPointTransform();
        _borderGraphicObject.Pen = new System.Windows.Media.Pen(
            new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromArgb(128, 0, 255, 0)), 10);
        GraphicObjectCollection.Add(_borderGraphicObject);
    }

    #endregion



    #region Methods

    /// <summary>
    /// Raises the VisualTool.Activated event.
    /// </summary>
    protected override void OnActivated(System.EventArgs e)
    {
        base.OnActivated(e);

        ImageViewer.ZoomChanged +=
            new System.EventHandler<Vintasoft.Imaging.UI.ZoomChangedEventArgs>(ImageViewer_ZoomChanged);
        ImageViewer.SizeChanged +=
            new System.Windows.SizeChangedEventHandler(ImageViewer_SizeChanged);
        ImageViewer.ScrollChanged +=
            new System.Windows.Controls.ScrollChangedEventHandler(ImageViewer_ScrollChanged);
        ImageViewer.ImageLoaded +=
            new System.EventHandler<Vintasoft.Imaging.ImageLoadedEventArgs>(ImageViewer_ImageLoaded);

        UpdateGraphicObjects();
    }

    /// <summary>
    /// Raises the VisualTool.Deactivated event.
    /// </summary>
    protected override void OnDeactivated(System.EventArgs e)
    {
        base.OnDeactivated(e);

        ImageViewer.ZoomChanged -= ImageViewer_ZoomChanged;
        ImageViewer.SizeChanged -= ImageViewer_SizeChanged;
        ImageViewer.ScrollChanged -= ImageViewer_ScrollChanged;
        ImageViewer.ImageLoaded -= ImageViewer_ImageLoaded;
    }

    /// <summary>
    /// Updates the graphic objects.
    /// </summary>
    void UpdateGraphicObjects()
    {
        System.Windows.Rect imageViewerRect = new System.Windows.Rect(
            ImageViewer.HorizontalOffset,
            ImageViewer.VerticalOffset,
            ImageViewer.ViewportWidth,
            ImageViewer.ViewportHeight);

        _fileNameGraphicObject.Rectangle = imageViewerRect;
        _zoomGraphicObject.Rectangle = imageViewerRect;
        _zoomGraphicObject.Text = string.Format("Zoom: {0}", ImageViewer.Zoom.ToString("0.0"));
        _zoomGraphicObject.TextAnchor = _zoomTextAnchor;


        Vintasoft.Imaging.VintasoftImage image = ImageViewer.Image;
        if (image == null)
        {
            _fileNameGraphicObject.Text = string.Empty;
            _fileNameGraphicObject.TextAnchor = _fileNameTextAnchor;
            _borderGraphicObject.Rectangle = System.Windows.Rect.Empty;
        }
        else
        {
            Vintasoft.Imaging.ImageSourceInfo info = image.SourceInfo;
            if (string.IsNullOrEmpty(info.Filename))
            {
                _fileNameGraphicObject.Text = string.Empty; ;
                _fileNameGraphicObject.TextAnchor = _fileNameTextAnchor;
            }
            else
            {
                string text = System.IO.Path.GetFileName(info.Filename);
                if (info.PageCount > 1)
                    text += string.Format(" (Page {0}/{1})", info.PageIndex + 1, info.PageCount);

                _fileNameGraphicObject.Text = text;
            }
            _fileNameGraphicObject.TextAnchor = _fileNameTextAnchor;

            _borderGraphicObject.Rectangle = new System.Windows.Rect(0, 0, image.Width, image.Height);
        }
    }

    /// <summary>
    /// Handles the SizeChanged event of the ImageViewer control.
    /// </summary>
    void ImageViewer_SizeChanged(object sender, System.Windows.SizeChangedEventArgs e)
    {
        UpdateGraphicObjects();
    }

    /// <summary>
    /// Handles the ZoomChanged event of the ImageViewer control.
    /// </summary>
    void ImageViewer_ZoomChanged(object sender, Vintasoft.Imaging.UI.ZoomChangedEventArgs e)
    {
        UpdateGraphicObjects();
    }

    /// <summary>
    /// Handles the ImageLoaded event of the ImageViewer control.
    /// </summary>
    void ImageViewer_ImageLoaded(object sender, Vintasoft.Imaging.ImageLoadedEventArgs e)
    {
        UpdateGraphicObjects();
    }

    /// <summary>
    /// Handles the ScrollChanged event of the ImageViewer control.
    /// </summary>
    void ImageViewer_ScrollChanged(object sender, System.Windows.Controls.ScrollChangedEventArgs e)
    {
        UpdateGraphicObjects();
    }

    #endregion

}
''' <summary>
''' Visual tool that draws static text (filename, current zoom factor) over image in
''' image viewer and draws a frame around image in image viewer:
''' </summary>
Private Class WpfGraphicObjectToolExample
    Inherits Vintasoft.Imaging.Wpf.UI.VisualTools.GraphicObjects.WpfGraphicObjectTool

    #Region "Fields"

    ''' <summary>
    ''' The graphic object that draws a filename over the image in image viewer.
    ''' </summary>
    Private _fileNameGraphicObject As New Vintasoft.Imaging.Wpf.UI.VisualTools.GraphicObjects.WpfTextGraphicObject()

    ''' <summary>
    ''' The font size of filename.
    ''' </summary>
    Private _fileNameEmSize As Double = 24

    ''' <summary>
    ''' The brush that should be used for drawing text of filename.
    ''' </summary>
    Private _fileNameForeground As System.Windows.Media.Brush = System.Windows.Media.Brushes.Salmon

    ''' <summary>
    ''' The anchor of text of filename.
    ''' </summary>
    Private _fileNameTextAnchor As Vintasoft.Imaging.AnchorType = Vintasoft.Imaging.AnchorType.Top

    ''' <summary>
    ''' The graphic object that draws image zoom factor over the image in image viewer.
    ''' </summary>
    Private _zoomGraphicObject As New Vintasoft.Imaging.Wpf.UI.VisualTools.GraphicObjects.WpfTextGraphicObject()

    ''' <summary>
    ''' The font size of zoom.
    ''' </summary>
    Private _zoomEmSize As Double = 20

    ''' <summary>
    ''' The brush of text of zoom.
    ''' </summary>
    Private _zoomForeground As System.Windows.Media.Brush = System.Windows.Media.Brushes.Lime

    ''' <summary>
    ''' The anchor of text of zoom.
    ''' </summary>
    Private _zoomTextAnchor As Vintasoft.Imaging.AnchorType = Vintasoft.Imaging.AnchorType.Bottom Or Vintasoft.Imaging.AnchorType.Right

    ''' <summary>
    ''' The graphic object that draws a frame around image in image viewer.
    ''' </summary>
    Private _borderGraphicObject As New Vintasoft.Imaging.Wpf.UI.VisualTools.GraphicObjects.WpfRectangularGraphicObject()

    ''' <summary>
    ''' The typeface of text.
    ''' </summary>
    Private _typeface As New System.Windows.Media.Typeface("Arial")

    #End Region



    #Region "Constructors"

    ''' <summary>
    ''' Initializes a new instance of the <see cref="WpfGraphicObjectToolExample"/> class.
    ''' </summary>
    Public Sub New()
        _fileNameGraphicObject.Typeface = _typeface
        _fileNameGraphicObject.EmSize = _fileNameEmSize
        _fileNameGraphicObject.FontBrush = _fileNameForeground
        _fileNameGraphicObject.TextAnchor = _fileNameTextAnchor
        GraphicObjectCollection.Add(_fileNameGraphicObject)

        _zoomGraphicObject.Typeface = _typeface
        _zoomGraphicObject.EmSize = _zoomEmSize
        _zoomGraphicObject.FontBrush = _zoomForeground
        _zoomGraphicObject.TextAnchor = _zoomTextAnchor
        GraphicObjectCollection.Add(_zoomGraphicObject)

        _borderGraphicObject.PointTransform = New Vintasoft.Imaging.Wpf.UI.VisualTools.WpfPixelsToImageViewerPointTransform()
        _borderGraphicObject.Pen = New System.Windows.Media.Pen(New System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromArgb(128, 0, 255, 0)), 10)
        GraphicObjectCollection.Add(_borderGraphicObject)
    End Sub

    #End Region



    #Region "Methods"

    ''' <summary>
    ''' Raises the VisualTool.Activated event.
    ''' </summary>
    Protected Overrides Sub OnActivated(e As System.EventArgs)
        MyBase.OnActivated(e)

        AddHandler ImageViewer.ZoomChanged, New System.EventHandler(Of Vintasoft.Imaging.UI.ZoomChangedEventArgs)(AddressOf ImageViewer_ZoomChanged)
        AddHandler ImageViewer.SizeChanged, New System.Windows.SizeChangedEventHandler(AddressOf ImageViewer_SizeChanged)
        AddHandler ImageViewer.ScrollChanged, New System.Windows.Controls.ScrollChangedEventHandler(AddressOf ImageViewer_ScrollChanged)
        AddHandler ImageViewer.ImageLoaded, New System.EventHandler(Of Vintasoft.Imaging.ImageLoadedEventArgs)(AddressOf ImageViewer_ImageLoaded)

        UpdateGraphicObjects()
    End Sub

    ''' <summary>
    ''' Raises the VisualTool.Deactivated event.
    ''' </summary>
    Protected Overrides Sub OnDeactivated(e As System.EventArgs)
        MyBase.OnDeactivated(e)

        RemoveHandler ImageViewer.ZoomChanged, AddressOf ImageViewer_ZoomChanged
        RemoveHandler ImageViewer.SizeChanged, AddressOf ImageViewer_SizeChanged
        RemoveHandler ImageViewer.ScrollChanged, AddressOf ImageViewer_ScrollChanged
        RemoveHandler ImageViewer.ImageLoaded, AddressOf ImageViewer_ImageLoaded
    End Sub

    ''' <summary>
    ''' Updates the graphic objects.
    ''' </summary>
    Private Sub UpdateGraphicObjects()
        Dim imageViewerRect As New System.Windows.Rect(ImageViewer.HorizontalOffset, ImageViewer.VerticalOffset, ImageViewer.ViewportWidth, ImageViewer.ViewportHeight)

        _fileNameGraphicObject.Rectangle = imageViewerRect
        _zoomGraphicObject.Rectangle = imageViewerRect
        _zoomGraphicObject.Text = String.Format("Zoom: {0}", ImageViewer.Zoom.ToString("0.0"))
        _zoomGraphicObject.TextAnchor = _zoomTextAnchor


        Dim image As Vintasoft.Imaging.VintasoftImage = ImageViewer.Image
        If image Is Nothing Then
            _fileNameGraphicObject.Text = String.Empty
            _fileNameGraphicObject.TextAnchor = _fileNameTextAnchor
            _borderGraphicObject.Rectangle = System.Windows.Rect.Empty
        Else
            Dim info As Vintasoft.Imaging.ImageSourceInfo = image.SourceInfo
            If String.IsNullOrEmpty(info.Filename) Then
                _fileNameGraphicObject.Text = String.Empty
                

                _fileNameGraphicObject.TextAnchor = _fileNameTextAnchor
            Else
                Dim text As String = System.IO.Path.GetFileName(info.Filename)
                If info.PageCount > 1 Then
                    text += String.Format(" (Page {0}/{1})", info.PageIndex + 1, info.PageCount)
                End If

                _fileNameGraphicObject.Text = text
            End If
            _fileNameGraphicObject.TextAnchor = _fileNameTextAnchor

            _borderGraphicObject.Rectangle = New System.Windows.Rect(0, 0, image.Width, image.Height)
        End If
    End Sub

    ''' <summary>
    ''' Handles the SizeChanged event of the ImageViewer control.
    ''' </summary>
    Private Sub ImageViewer_SizeChanged(sender As Object, e As System.Windows.SizeChangedEventArgs)
        UpdateGraphicObjects()
    End Sub

    ''' <summary>
    ''' Handles the ZoomChanged event of the ImageViewer control.
    ''' </summary>
    Private Sub ImageViewer_ZoomChanged(sender As Object, e As Vintasoft.Imaging.UI.ZoomChangedEventArgs)
        UpdateGraphicObjects()
    End Sub

    ''' <summary>
    ''' Handles the ImageLoaded event of the ImageViewer control.
    ''' </summary>
    Private Sub ImageViewer_ImageLoaded(sender As Object, e As Vintasoft.Imaging.ImageLoadedEventArgs)
        UpdateGraphicObjects()
    End Sub

    ''' <summary>
    ''' Handles the ScrollChanged event of the ImageViewer control.
    ''' </summary>
    Private Sub ImageViewer_ScrollChanged(sender As Object, e As System.Windows.Controls.ScrollChangedEventArgs)
        UpdateGraphicObjects()
    End Sub

    #End Region

End Class