2006 年的注释图像控件
一篇关于 VS 2005 中注释图像控件的文章。

引言
自从我更新带注释图像控件已经大约两年了,早就应该进行一次大修:删除大量错误、迁移到 VS2005、架构更改、速度改进、额外功能等。对于那些没有阅读过我之前关于此控件的其他文章的人,这里简要介绍一下它的功能
- 显示图像并缩放
- 以叠加方式显示蒙版
- 以叠加方式显示注释
- 交互式创建注释并保存/加载它们
- 编辑注释:移动注释,移动和删除点...
背景
我之前关于这个主题的文章可能仍然有帮助。
Using the Code
该控件应添加到另一个项目中,并为其分配一个位图。然后可以添加/加载/创建注释和蒙版,并将它们添加到各自的集合中。
Public Sub New()
MyBase.New()
InitializeComponent()
'Add the custom control
Me._annotatedImage = New AnnotatedImage
Me.Controls.Add(Me.AnnotatedImage)
'Make sure image form is maximized
'so we can measure the maximal clientsize
Me.SuspendLayout()
Me.WindowState = FormWindowState.Normal
Dim rectScreen As Rectangle = _
Screen.PrimaryScreen.WorkingArea
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.MeasureAnnotationEventHandler))
Me.AnnotatedImage.AddContextMenuItem("Measure", _
AnnotatedImage.ContextMenus.AnnotationContainer, _
New System.EventHandler(AddressOf _
Me.MeasureAnnotationEventHandler))
Me.AnnotatedImage.AddContextMenuItem("Morphology", _
AnnotatedImage.ContextMenus.Mask, _
New System.EventHandler(AddressOf _
Me.MaskMorpholgyEventHandler))
Me.AnnotatedImage.AddContextMenuItem("Save", _
AnnotatedImage.ContextMenus.Mask, _
New System.EventHandler(AddressOf Me.MaskSaveEventHandler))
Me.ResumeLayout()
End Sub
带注释图像控件使用一系列事件与其宿主进行通信(另请参阅可下载的帮助文件)。事件列表

事件处理程序
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
...
在对annotatedImage
控件的集合执行大量更新时,关闭重绘非常重要,可以通过将Updating
属性设置为True
来实现。 将此属性重置为False
时,将触发Updated
事件,允许宿主应用程序执行必要的更新。此外,除非绝对必要,否则避免在Updating
属性仍然为True
时响应其他事件!
在更新内部集合期间不处理事件的一个例子是控件绘制这些集合的树视图
Private Sub annotatedImage_CollectionsChanged(ByVal sender As Object, _
ByVal e As CollectionChangedEventArgs) _
Handles annotatedImage.MaskCollectionChanged, _
annotatedImage.AnnotationCollectionChanged, _
annotatedImage.AnnotationContainerCollectionChanged
If Me.annotatedImage.Updating = False Then
InvokeSynchronizeTree()
End Sub
键盘绑定、交互式创建和操作
一些默认的键盘绑定是
- 鼠标滚轮,Z,Shift-Z:缩放
- 鼠标中键拖动:当图像大于桌面时移动图像。如果它较小并且缩放比例小于1,它将弹出一个放大镜。
带注释的图像控件具有用于交互式创建和操作注释的绑定。右键单击会弹出一个上下文菜单,允许创建注释和注释容器。

编辑注释时,默认操作是选择注释。然后可以通过拖动来移动它,或者可以使用删除键删除它。双击将启动其属性对话框。如果在选择期间使用Shift键,则将选择整个注释,如果使用Control键,则只能选择点。


演示
包含的 sRGBViewer 应用程序是一个简单的查看器,允许创建和编辑注释,并将保存它们。请注意,图像实际上可以驻留在(并保存回)网站上。这实际上就是我使用它的方式:作为基于 Web 的医疗图片相册系统的智能客户端。

关注点
实际上,是时候使用 GDI+ 实现硬件加速了,正如几年前宣布的那样,这在 Vista 中已经成为现实。不过,我还没有尝试过。当反复测试一个点是否在其内部(命中测试)时,Regions 的实现仍然非常慢。
历史
2006 年 6 月 27 日的版本:此控件的第一个版本始于 2003 年,但由于根本性的变化,与旧版本相关的文章不再相关。