This article contains a zip file with projects showing how to zoom in and out of an image programmatically while keeping the center of the viewable area
centered. The zip contains both C# and VB projects using DotImage 11.1
The concept is that when you zoom in/out you need to calculate the correct scroll position and programmatically scroll the control on the fly. This must be done on both zoom in and zoom out
C#
///
/// This code will apply a new zoom to the viewer,
/// keeping the center pixel centered after the zoom.
///
/// The new zoom level.
private void ZoomViewer(double newZoomLevel)
{
// Limit the zoom amount.
if (newZoomLevel < 1.0) newZoomLevel = 1.0;
if (newZoomLevel > 20.0) newZoomLevel = 20.0;
double oldZoom = this._viewer.Zoom;
if (newZoomLevel == oldZoom) return;
// Get the current viewable area.
Size imageSize = this._viewer.Image.Size;
Size clientSize = this._viewer.ClientSize;
int width = Convert.ToInt32(Math.Min((clientSize.Width / oldZoom), (imageSize.Width / oldZoom)));
int height = Convert.ToInt32(Math.Min((clientSize.Height / oldZoom), (imageSize.Height / oldZoom)));
int left = Convert.ToInt32(Math.Abs(this._viewer.ScrollPosition.X) / oldZoom);
int top = Convert.ToInt32(Math.Abs(this._viewer.ScrollPosition.Y) / oldZoom);
Rectangle rc = new Rectangle(left, top, width, height);
// Now we have the center pixel.
Point centerPixel = new Point(rc.Width / 2 + rc.Left, rc.Height / 2 + rc.Top);
// Calculate the new scroll position.
width = Convert.ToInt32(Math.Min((clientSize.Width / newZoomLevel), (imageSize.Width / newZoomLevel)));
height = Convert.ToInt32(Math.Min((clientSize.Height / newZoomLevel), (imageSize.Height / newZoomLevel)));
left = Convert.ToInt32(Math.Abs(centerPixel.X - (width / 2)) * newZoomLevel);
top = Convert.ToInt32(Math.Abs(centerPixel.Y - (height / 2)) * newZoomLevel);
if (left < 0) left = 0;
if (top < 0) top = 0;
// Using SuspendLayout and ResumeLayout will keep it from flickering.
this._viewer.SuspendLayout();
this._viewer.Zoom = newZoomLevel;
this._viewer.ScrollPosition = new Point(-left, -top);
this._viewer.ResumeLayout();
}
VB.NET
'/
'/ This code will apply a new zoom to the viewer,
'/ keeping the center pixel centered after the zoom.
'/
'/ The new zoom level.
Private Sub ZoomViewer(ByVal NewZoomLevel As Double)
' Limit the zoom amount.
If NewZoomLevel < 1.0 Then
NewZoomLevel = 1.0
End If
If NewZoomLevel > 20.0 Then
NewZoomLevel = 20.0
End If
Dim oldZoom As Double = Me._viewer.Zoom
If NewZoomLevel = oldZoom Then
Return
End If
' Get the current viewable area.
Dim imageSize As Size = Me._viewer.Image.Size
Dim clientSize As Size = Me._viewer.ClientSize
Dim width As Integer = Convert.ToInt32(Math.Min((clientSize.Width / oldZoom), (imageSize.Width / oldZoom)))
Dim height As Integer = Convert.ToInt32(Math.Min((clientSize.Height / oldZoom), (imageSize.Height / oldZoom)))
Dim left As Integer = Convert.ToInt32(Math.Abs(Me._viewer.ScrollPosition.X) / oldZoom)
Dim top As Integer = Convert.ToInt32(Math.Abs(Me._viewer.ScrollPosition.Y) / oldZoom)
Dim rc As Rectangle = New Rectangle(left, top, width, height)
' Now we have the center pixel.
Dim centerPixel As Point = New Point(rc.Width / 2 + rc.Left, rc.Height / 2 + rc.Top)
' Calculate the new scroll position.
width = Convert.ToInt32(Math.Min((clientSize.Width / NewZoomLevel), (imageSize.Width / NewZoomLevel)))
height = Convert.ToInt32(Math.Min((clientSize.Height / NewZoomLevel), (imageSize.Height / NewZoomLevel)))
left = Convert.ToInt32(Math.Abs(centerPixel.X - (width / 2)) * NewZoomLevel)
top = Convert.ToInt32(Math.Abs(centerPixel.Y - (height / 2)) * NewZoomLevel)
If left < 0 Then
left = 0
End If
If top < 0 Then
top = 0
End If
' Using SuspendLayout and ResumeLayout will keep it from flickering.
Me._viewer.SuspendLayout()
Me._viewer.Zoom = NewZoomLevel
Me._viewer.ScrollPosition = New Point(-left, -top)
Me._viewer.ResumeLayout()
End Sub
Original Article:
Q10173 - HOWTO: Apply a zoom while keeping the image centered (WinForms)