Click here to Skip to main content
13,148,503 members (53,887 online)
Click here to Skip to main content
Add your own
alternative version


55 bookmarked
Posted 1 Dec 2004

The Annotated Image Control in 2006

, 27 Jun 2006
Rate this:
Please Sign up or sign in to vote.
An article on the Annotated Image control in VS 2005
Screenshot - sRGBToolbox.jpg


It's been about two years since I updated my Annotated Image control and an overhaul is long overdue: removal of a plethora of bugs, migration to VS2005, architectural changes, speed improvements, extra functionality, etc. For those who haven't read my other articles on previous incarnations of this control, here is briefly what it will do:

  • Display an image and zoom it
  • Display a mask in overlay
  • Display annotations in overlay
  • Create annotations interactively and save/load them
  • Edit annotations: move annotation, move and delete points...


My older articles on this subject might still help.

Using the Code

The control should be added to another project and a bitmap assigned to it. Annotations and masks can then be added/loaded/created and added to their respective collections.

Public Sub New() 

    'Add the custom control 
    Me._annotatedImage = New AnnotatedImage

    'Make sure image form is maximized 
    'so we can measure the maximal clientsize 
    Me.WindowState = FormWindowState.Normal 
    Dim rectScreen As Rectangle = _
    Dim objCurrentSize As Size = Me.Size 
    Me.Width = rectScreen.Width 
    'Dunno why, but we need to subtract 20 
    Me.Height = rectScreen.Height - 40
    Me.AnnotatedImage.MaximimumSize = Me.ClientSize 
    Me.ClientSize = objCurrentSize 

        'Load an image, e.g. from a command line argument
        Me.AnnotatedImage.LoadBitmap(new URI("C:\temp\anImage.jpg"))

    'Show annotations manager and add some menus 
    Me.AnnotatedImage.AddContextMenuItem("Measure", _
        AnnotatedImage.ContextMenus.Annotation, _
        New System.EventHandler(AddressOf _
    Me.AnnotatedImage.AddContextMenuItem("Measure", _
        AnnotatedImage.ContextMenus.AnnotationContainer, _
        New System.EventHandler(AddressOf _
    Me.AnnotatedImage.AddContextMenuItem("Morphology", _
        AnnotatedImage.ContextMenus.Mask, _
        New System.EventHandler(AddressOf _
    Me.AnnotatedImage.AddContextMenuItem("Save", _
        AnnotatedImage.ContextMenus.Mask, _
        New System.EventHandler(AddressOf Me.MaskSaveEventHandler)) 

End Sub

The annotated image control communicates with its host using a series of events (see also the downloadable help file). The events list:

Screenshot - Events.png

Event handlers:

Private Sub _annotatedImage_ItemSelected(ByVal sender _
    As Object) Handles _annotatedImage.ItemSelected
End Sub

Private Sub _annotatedImage_Updated(ByVal sender _
    As Object) Handles _annotatedImage.Updated
End Sub

Private Sub AnnotatedImageResize(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles _annotatedImage.Resize
    'Resize parent form to user control. Causes refresh ....
    Debug.WriteLine("Received resize event from AnnotatedImage," & _ 
                    " resizing client area", "AnnotatedsRGBImageResize")
    Dim iControlWidth As Integer = AnnotatedImage.Width
    Dim iControlHeight As Integer = AnnotatedImage.Height
    AnnotatedImage.Location = New Point(0, 0)
    Me.stbImage.Location = New Point(0, iControlHeight)
    Me.stbImage.Width = iControlWidth
    Me.ClientSize = New Size(Math.Max(iControlWidth, 600), _
        iControlHeight + stbImage.Height)
End Sub

Private Sub annotatedImage_BitmapChanged(ByVal sender As Object) _
    Handles _annotatedImage.BitmapChanged
End Sub

It is very important to turn off redrawing while performing extensive updates on the collections of the annotatedImage control by setting the Updating property to True. When resetting this property to False, the Updated event will be fired, allowing the host application to perform necessary updates. Also, avoid reacting to other events when the Updating property is still True, unless absolutely necessary!

An example of not handling events during updating of the internal collections is a control drawing a treeview of these collections:

Private Sub annotatedImage_CollectionsChanged(ByVal sender As Object, _
    ByVal e As CollectionChangedEventArgs) _ 
    Handles annotatedImage.MaskCollectionChanged, _
    annotatedImage.AnnotationCollectionChanged, _ 

    If Me.annotatedImage.Updating = False Then
End Sub

Key Bindings, Interactive Creation and Manipulation

Some of the default key bindings are:

  • Mouse wheel, Z, Shift-Z: Zoom
  • Middle mouse button drag: Move the image when it is larger than the desktop. If it is smaller and the zoom is smaller than 1, it will bring up a magnifying glass.

The annotated image control has bindings for interactive creation and manipulation of annotations. Right-clicking brings up a context-sensitive menu that allows the creation of annotations and annotation containers.

Screenshot - StartAnnotationCreation.jpg

When editing an annotation, the default action is selecting an annotation. You can then move it by dragging it or you can delete it using the delete key. Double-clicking will launch its properties dialog. If you use the Shift key during selection, the whole annotation will be selected, if you use the Control key, only the points can be selected.


The included sRGBViewer application is a simple viewer that allows creation and editing of annotations, and will save them. Note that the images can actually reside (and be saved back) on a website. This is actually how I use it: as a smart client for a web-based medical picture album system.

Screenshot - sRGBViewer.jpg

Points of Interest

It really is about time the GDI+ implementation used hardware acceleration, as announced years ago, and this is now a reality in Vista. I haven't tried it yet, though. The implementation of Regions is still terribly slow when testing repeatedly whether a point is inside it (hit testing).


Version of June 27, 2006: First versions of this control date from 2003, but the articles related to the older versions are no longer relevant due to fundamental changes.


This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)


About the Author

Software Developer (Senior)
Belgium Belgium
Physicist, Biomedical Engineer, Phd in engineering. Specific expertise is in medical photography and it's related image processing, and in colourimetry.

You may also be interested in...


Comments and Discussions

QuestionHow to extend this framework? Pin
romias27-Oct-10 14:57
memberromias27-Oct-10 14:57 
AnswerRe: How to extend this framework? Pin
yvdh27-Oct-10 21:36
memberyvdh27-Oct-10 21:36 
GeneralRe: How to extend this framework? [modified] Pin
romias28-Oct-10 5:23
memberromias28-Oct-10 5:23 
GeneralRe: How to extend this framework? Pin
yvdh1-Nov-10 6:21
memberyvdh1-Nov-10 6:21 
GeneralLatest Version Pin
coolpjmartin29-Jun-09 22:18
membercoolpjmartin29-Jun-09 22:18 
GeneralLatest version at Codeplex Pin
yvdh17-Jun-07 7:30
memberyvdh17-Jun-07 7:30 
GeneralRe: Latest version at Codeplex [modified] Pin
yvdh23-Apr-09 2:04
memberyvdh23-Apr-09 2:04 
GeneralRe: Latest version at Codeplex Pin
aarrabi7616-Jun-09 23:56
memberaarrabi7616-Jun-09 23:56 
GeneralSelection Info Pin
abakshi12-Jun-07 6:11
memberabakshi12-Jun-07 6:11 
GeneralRe: Selection Info Pin
yvdh12-Jun-07 13:53
memberyvdh12-Jun-07 13:53 
GeneralRe: Selection Info Pin
abakshi20-Jun-07 16:18
memberabakshi20-Jun-07 16:18 
GeneralRe: Selection Info Pin
yvdh20-Jun-07 22:16
memberyvdh20-Jun-07 22:16 
klaus@gubbernet.com11-May-07 1:02
memberklaus@gubbernet.com11-May-07 1:02 
GeneralRe: NOT COMPLETE!! Pin
yvdh11-May-07 2:21
memberyvdh11-May-07 2:21 
GeneralRe: NOT COMPLETE!! Pin
klaus@gubbernet.com11-May-07 2:47
memberklaus@gubbernet.com11-May-07 2:47 
GeneralUse in C# Pin
Reanalyse12-Jun-05 12:53
memberReanalyse12-Jun-05 12:53 
GeneralRe: Use in C# Pin
yvdh12-Jun-05 22:55
memberyvdh12-Jun-05 22:55 
GeneralAWESOME! Pin
onyak3-Dec-04 8:58
memberonyak3-Dec-04 8:58 
GeneralGreat, this just comes in time Pin
Marc Sommer2-Dec-04 21:28
memberMarc Sommer2-Dec-04 21:28 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170924.2 | Last Updated 27 Jun 2006
Article Copyright 2004 by yvdh
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid