Zooming to fit a region in a ScrollableControl
I suspect the titles of these last pair of articles are a touch
misleading as they talk about extended zoom operations without
actually describing a zoom process (as this is already part of
other ImageBox articles. Unfortunately I can't really think
of better titles and the theory is generic enough to be applied
to any type of zooming, not just the ImageBox
.
My previous article touched on zooming in a
ScrollableControl
while keeping the content correctly aligned
to a fixed point, usually the mouse position prior to the zoom.
This article expands on that with another new feature in the
upcoming ImageBox
update, zooming to a given region. You've
probably seen this behaviour in other paint programs, where you
select a Zoom tool, draw a rectangle, and the document is
automatically zoomed to fit.
Again, this is actually quite simple to achieve and this blog
post is pretty much just a reference to me of how I did this so
I don't forget next time I want something similar! We'll start
off by quickly describing a method that I forgot to include in
the previous post - CenterAt
. This simple method centers the
view port on the given document location. This use useful for
when you want to use ScrollTo
without providing a relative
offset... or for centering the display on a selection rectangle.
public virtual void CenterAt(Point imageLocation)
{
this.ScrollTo(imageLocation, new Point(this.ClientSize.Width / 2, this.ClientSize.Height / 2));
}
Very straightforward, it simply calls ScrollTo
, using the
center of the control as the offset. Now for the actual
ZoomToRegion
method:
public virtual void ZoomToRegion(RectangleF rectangle)
{
double ratioX;
double ratioY;
int cx;
int cy;
ratioX = this.ClientSize.Width / rectangle.Width;
ratioY = this.ClientSize.Height / rectangle.Height;
cx = (int)(rectangle.X + (rectangle.Width / 2));
cy = (int)(rectangle.Y + (rectangle.Height / 2));
this.Zoom = (int)(Math.Min(ratioX, ratioY) * 100);
this.CenterAt(new Point(cx, cy));
}
This accepts a RectangleF
structure (you could use a
Rectangle
, but then if you attempt to draw selection regions
on a zoomed out document, rounding from float
to int
would
render your selections useless), and it then calculates a new
zoom factor and offset.
- First, the ration of the width and height of the region against the width and height of the view port is calculated
- We use the smallest ratio (to ensure if that everything you selected appears when the zoom is applied) to calculate the new zom level
- After this, we define the center of the rectangle
- With all the calculations done, we set the zoom level of the control
- And finally, we call our new
CenterAt
method to center the view port on the center of the source region
In the actual ImageBox
control, a new SelectionMode
has been
added - Zoom
. As the name somewhat logically suggests, when
this mode is active, after the user draws a selection rectangle,
the control then zooms to match the rectangle they have drawn.
This updated mode is called from the OnSelected
method, as
follows:
if (this.SelectionRegion != null && this.SelectionRegion.Width > ImageBox.SelectionDeadZone && this.SelectionRegion.Height > ImageBox.SelectionDeadZone)
{
this.ZoomToRegion(this.SelectionRegion);
this.SelectionRegion = RectangleF.Empty;
}
The mysterious ImageBox.SelectionDeadZone
field is a constant
currently set to 5, and basically ensures the user selects a
valid rectangle first - when I was testing the first iteration
of this code, having the mouse wobble as you clicked the control
was enough to generate a 1x1 rectangle, definitely not a good
user experience!
The only disadvantage is this functionality only lends itself to zooming it, and not out.
Update History
- 2012-08-30 - First published
- 2020-11-21 - Updated formatting
Related articles you may be interested in
- Displaying multi-page tiff files using the ImageBox control and C#
- Adding drag handles to an ImageBox to allow resizing of selection regions
- ImageBox 1.1.4.0 update
- ImageBox and TabList update's - virtual mode, pixel grid, bug fixes and more!
- ImageBox update, version 1.1.0.0
- Zooming into a fixed point on a ScrollableControl
- Arcade explosion generator
- Creating an image viewer in C# Part 5: Selecting part of an image
- Extending the ImageBox component to display the contents of a PDF file using C#
- Creating a scrollable and zoomable image viewer in C# Part 4
- Creating a scrollable and zoomable image viewer in C# Part 3
- Creating a scrollable and zoomable image viewer in C# Part 2
- Creating a scrollable and zoomable image viewer in C# Part 1
Leave a Comment
While we appreciate comments from our users, please follow our posting guidelines. Have you tried the Cyotek Forums for support from Cyotek and the community?