Tuesday, March 26, 2013

How to zoom a picturebox with the mouse in C#

Zooming a picturebox with the mouse wheel is something really useful, and it's achieved with the OnMouseWheel event of the picturebox. But the picturebox doesn't have an OnMouseWheel event you can set, that means you need to override the standard picturebox method. This is a really simple operation, you can just create a method with this signature:
protected override void OnMouseWheel(MouseEventArgs mea)
Then you can put all the zoom code in there.
The only thing you need to understand the zoom code is basic math. The zoom works by defining a minumum/maximum magnification and by defining by how much you want to zoom at every movement of the mouse wheel.
In this example the min/max will be 15, and the zoom factor will be 1.25. We will NOT change the image in any way, the only thing that gets bigger or smaller is the picturebox itself, that's why i suggest you set your picturebox size mode to "Zoom".
Here's a simple implementation:
protected override void OnMouseWheel(MouseEventArgs mea)
{
    // Override OnMouseWheel event, for zooming in/out with the scroll wheel
    if (pictureBox1.Image != null)
    {
        // If the mouse wheel is moved forward (Zoom in)
        if (mea.Delta > 0)
        {
            // Check if the pictureBox dimensions are in range (15 is the minimum and maximum zoom level)
            if ((pictureBox1.Width < (15 * this.Width)) && (pictureBox1.Height < (15 * this.Height)))
            {
                // Change the size of the picturebox, multiply it by the ZOOM FACTOR
                pictureBox1.Width = (int)(pictureBox1.Width * 1.25);
                pictureBox1.Height = (int)(pictureBox1.Height * 1.25);
            }
        }
        //Zoom out
        else
        {
            // Check if the pictureBox dimensions are in range (15 is the minimum and maximum zoom level)
            if ((pictureBox1.Width > (this.Width / 15)) && (pictureBox1.Height > (this.Height / 15)))
            {
                // Change the size of the picturebox, divide it by the ZOOM FACTOR
                pictureBox1.Width = (int)(pictureBox1.Width / 1.25);
                pictureBox1.Height = (int)(pictureBox1.Height / 1.25);
            }
        }
    }
}
This code will work and it will zoom your picturebox. There is only a little problem, depending on how you want your picturebox to behave. In this code the picturebox will always stay in the same position, this means that the upper left corner will be in a fixed position, and everything else will be shifting. If you want the picturebox to follow your mouse cursor while you zoom, you need to add a little formula. This will do the trick for the Zoom In part:
pictureBox1.Top = (int)(mea.Y - 1.25 * (mea.Y - pictureBox1.Top));
pictureBox1.Left = (int)(mea.X - 1.25 * (mea.X - pictureBox1.Left));
And this is what you need to add in the Zoom Out part:
pictureBox1.Top = (int)(mea.Y - 0.80 * (mea.Y - pictureBox1.Top));
pictureBox1.Left = (int)(mea.X - 0.80 * (mea.X - pictureBox1.Left));
As you can see, only the zoom factor changes. Let's put everything together and will get this:
protected override void OnMouseWheel(MouseEventArgs mea)
{
    // Override OnMouseWheel event, for zooming in/out with the scroll wheel
    if (pictureBox1.Image != null)
    {
        // If the mouse wheel is moved forward (Zoom in)
        if (mea.Delta > 0)
        {
            // Check if the pictureBox dimensions are in range (15 is the minimum and maximum zoom level)
            if ((pictureBox1.Width < (15 * this.Width)) && (pictureBox1.Height < (15 * this.Height)))
            {
                // Change the size of the picturebox, multiply it by the ZOOMFACTOR
                pictureBox1.Width = (int)(pictureBox1.Width * 1.25);
                pictureBox1.Height = (int)(pictureBox1.Height * 1.25);

                // Formula to move the picturebox, to zoom in the point selected by the mouse cursor
                pictureBox1.Top = (int)(mea.Y - 1.25 * (mea.Y - pictureBox1.Top));
                pictureBox1.Left = (int)(mea.X - 1.25 * (mea.X - pictureBox1.Left));
            }
        }
        else
        {
            // Check if the pictureBox dimensions are in range (15 is the minimum and maximum zoom level)
            if ((pictureBox1.Width > (this.Width / 15)) && (pictureBox1.Height > (this.Height / 15)))
            {
                // Change the size of the picturebox, divide it by the ZOOMFACTOR
                pictureBox1.Width = (int)(pictureBox1.Width / 1.25);
                pictureBox1.Height = (int)(pictureBox1.Height / 1.25);

                // Formula to move the picturebox, to zoom in the point selected by the mouse cursor
                pictureBox1.Top = (int)(mea.Y - 0.80 * (mea.Y - pictureBox1.Top));
                pictureBox1.Left = (int)(mea.X - 0.80 * (mea.X - pictureBox1.Left));
            }
        }
    }
}

4 comments:

  1. it works for me, only a question:
    How do you obtain 0.80 for zoom out?

    ReplyDelete
  2. PictureBox1.Top and PictureBox1.Left hides a part of a picture in the left side so How can i adjust this?

    ReplyDelete

prettyprint