How to implement a Magnifying Glass in .NET version of DicomObjects

It is possible to implement a magnifying glass tool in DicomObjects.NET.This functionality can be achieved by using a second DicomImage which is a copy of the original image (scaled, zoomed and scrolled accordingly) and overlaying onto the original image. Because the new image is a "Clone" of the original, it shares the same underlying DataSet, and it therefore uses negligable memory and takes a tiny amount of time to create.

The mouse cursor can be used to control the position of the magnifying glass easily thanks to the DicomViewer Mouse events.

The Magnifying glass (refered to as ZoomImage in the following code) can be initialised through the DicomViewer Mouse Down event.

Dim ZoomImage As DicomImage

Private Sub Viewer_MouseDown(ByVal sender As Object \
    , ByVal e As System.Windows.Forms.MouseEventArgs) Handles Viewer.MouseDown
'Width and Height of the Image Object to be used as our magnifying Glass.
h = 0.1
w = 0.1
Dim p As System.Drawing.Point = New Point(e.X, e.Y)
 If Viewer.ImageIndex(p) >= 0 Then
  ZoomImage = Viewer.Images(Viewer.Images.Count - 1).Clone(True)
  ZoomImage.StretchToFit = False
  ZoomImage.Zoom = DicomGlobal.Zoom(Viewer.CurrentImage.Matrix(Viewer)) * 5 ' any value you like 
  zooming = True
  Viewer.CurrentIndex = 0
 End If
End Sub

The ZoomImage (Magnifying Glass) can be correctly scrolled and positioned by using the following routine.

Sub SetMagnifier(ByVal p As System.Drawing.Point)
Dim IMIndex As Integer = Viewer.ImageIndex(p)
 If IMIndex >= 0 Then
  'Convert the ClientSize from screen to image coordinates 
  Dim imageToScreenTransform As System.Drawing.Drawing2D.Matrix = ZoomImage.Matrix(Viewer)
  Dim scaleImageToScreen As Single = DicomGlobal.Zoom(imageToScreenTransform)
  ' And scroll to show the right place 
  Dim imagePoint As PointF = Viewer.ImagePosition(p)
  Dim sx As Single = (imagePoint.X * scaleImageToScreen) - (w * Viewer.ClientSize.Width / 2)
  Dim sy As Single = (imagePoint.Y * scaleImageToScreen) - (h * Viewer.ClientSize.Height / 2)
  Dim sclXY As Point
  sclXY.X = -sx
  sclXY.Y = -sy
  ZoomImage.Scroll = sclXY
  'now move the magnify viewer within the main viewer
  Dim Rect As New RectangleF
  Rect.X = (p.X / Viewer.Width) - w / 2
  Rect.Y = (p.Y / Viewer.Height) - h / 2
  Rect.Width = w
  Rect.Height = h
  ZoomImage.Area = Rect
 End If
End Sub

When the mouse cursor is moved the ZoomImage needs to be repositioned, the DicomViewer Mouse move event simply calls the SetMagnifier routine and passes to it the new Mouse x,y coordinates expressed as a system.Drawing.Point.

Private Sub Viewer_MouseMove(ByVal sender As Object  \
    , ByVal e As System.Windows.Forms.MouseEventArgs) Handles Viewer.MouseMove
 Dim p As Point
 p.X = e.X
 p.Y = e.Y
 If zooming Then SetMagnifier(p)
End Sub

Finally when the mouse button is released the ZoomImage is removed from the DicomViewer.

Private Sub Viewer_MouseUp(ByVal sender As Object  \
    , ByVal e As System.Windows.Forms.MouseEventArgs) Handles Viewer.MouseUp
 If zooming Then
  zooming = False
  Viewer.Images.Remove(Viewer.Images(Viewer.Images.Count - 1))
  ImagePos.Text = ""
 End If
End Sub

Developers who have previously use the COM version of DicomObjects will notice that the ActualZoom, ActualScroll properties no longer exist, instead DicomImage has a matrix property which can be used to transform between DicomViewer and image coordinates.

Special Thanks to: Rodney Richardson