How to zoom at a point in picturebox

c#, c#-4.0, mousewheel, visual-studio-2010, zooming

Solution

Here is how you achieve this (description below code):

Variables

// this tracks the transformation applied to the PictureBox's Graphics
private Matrix transform = new Matrix();      
public static double s_dScrollValue = 1.01; // zoom factor

Paint code

private void m_Picturebox_Canvas_Paint(object sender, PaintEventArgs e)
{
   Graphics g = e.Graphics;
   g.Transform = transform;
}

Scroll-Event code

protected override void OnMouseWheel(MouseEventArgs mea)
{
    m_Picturebox_Canvas.Focus();
    if (m_Picturebox_Canvas.Focused == true && mea.Delta != 0)
    {
        ZoomScroll(mea.Location, mea.Delta > 0);
    }
}

Zoom function

//FUNCTION FOR MOUSE SCROL ZOOM-IN
private void ZoomScroll(Point location, bool zoomIn)
{
    // make zoom-point (cursor location) our origin
    transform.Translate(-location.X, -location.Y);

    // perform zoom (at origin)
    if(zoomIn)
        transform.Scale(s_dScrollValue, s_dScrollValue);
    else
        transform.Scale(1 / s_dScrollValue, 1 / s_dScrollValue);

    // translate origin back to cursor
    transform.Translate(location.X, location.Y);

    m_Picturebox_Canvas.Invalidate();
}

Description

First of all, as you can see I combined your two zoom methods to one method: `ZoomScroll` Otherwise we would duplicate a lot of logic...

So what is done here? I guess it is clear that we need to also apply a translation to the `Graphics` object. We "accumulate" all transformation applied to the `PictureBox` in a `Matrix` field.

You successfully scaled your image, but always with the origin (upper-left corner of the `PictureBox`) as the locical center of your scaling-operation - that is just how `Scale`/`ScaleTransform` works! So in order to scale at a different point the following steps are needed:

- translate the world, so that the point you want to scale at is the new origin (e.g. your cursor is at `12|34`, so we translate by `-12|-34`)

- now that the desired spot is our new origin, scale

- translate the world back, so the original point ends up under your cursor again

Problem

This is my code. I am able to zoom the picturebox but not at a point. How to zoom to a mouse point when i rotate the mouse wheel? The variables are:- ``` private double m_dZoomscale = 1.0; //THIS IS THE ZOOM SCALE TO WHICH EACH OBJECT //ARE ZOOMED IN THE CANVAS public static double s_dScrollValue = .01; //scale factor value for mouse scroll zooming ``` The paint code is:- ``` private void m_Picturebox_Canvas_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; g.ScaleTransform((float)m_dZoomscale, (float)m_dZoomscale); } ``` The main code is:- ``` protected override void OnMouseWheel(MouseEventArgs mea) { m_Picturebox_Canvas.Focus(); if (m_Picturebox_Canvas.Focused == true) { if (mea.Delta > 0) { ZoomInScroll(); } else if (mea.Delta < 0) { ZoomOutScroll(); } } } ``` The sub functions are as follows:- ``` //FUNCTION FOR MOUSE SCROL ZOOM-IN private void ZoomInScroll() { m_dZoomscale = m_dZoomscale + s_dScrollValue; m_Picturebox_Canvas.Invalidate(); } //FUNCTION FOR MOUSE SCROL ZOOM-IN private void ZoomOutScroll() { m_dZoomscale = m_dZoomscale - s_dScrollValue; m_Picturebox_Canvas.Invalidate(); } ```

Original source