Search

Atalasoft Knowledge Base

HOWTO: Apply a zoom while keeping the image centered (WinForms)

Administrator
DotImage

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)

Details
Last Modified: 6 Years Ago
Last Modified By: Administrator
Type: HOWTO
Article not rated yet.
Article has been viewed 1.9K times.
Options
Also In This Category