0

i have a picturebox that contain an image (1280 X 720), i want to create a second picturebox that contain a zoomed version of the image centered around the cursor (for example a 40 X 40 square around the cursor zomed to be in a 120 X 120 square picturebox) that follow the cursor in real time in real time (if it's possible also to have a cross in the middle of the picturebox that show the precise placing of the cursor is even better).

private void Button1_Click(object sender, EventArgs e)
     {
         openFileDialog1.Filter = "All jpg files (*.jpg)|*.jpg";
         if (openFileDialog1.ShowDialog() == DialogResult.OK)
         {
             Bitmap img = new Bitmap(openFileDialog1.FileName);
             double imageHeight = img.Height;
             double imageWidth = img.Width;
             pictureBox1.Image = img;

         }
     }
private void PictureBox1_MouseMove(object sender, MouseEventArgs e)
     {
         int xupleft = e.X - 20;
         int yupleft = e.Y - 20;

         Rectangle myrectangle = new Rectangle(xupleft, yupleft, 40, 40);

         pictureBox2.Image = pictureBox1.Image;

     }
Matteo Sala
  • 43
  • 10
  • - Hints: You could create an enlarged bitmap at class level after the zoom factor has been set. Then code the pbox2.MouseMove event. It could display a portion of the scaled bitmap. To create you would use the Bitmap(Image, Size) constructor. You could use the pbox2.Paint event to draw a rectangle using the e.Graphics.DrawImage method with two rentangles. And for the crosshair cursor you could use pbox1.Paint and 2 DrawLine calls.. To find the source rect you would need to calculate with the zoom factor.. – TaW Aug 04 '19 at 15:05
  • Using a similar technique you could also draw onto the original pbox and discard pbox2.. – TaW Aug 04 '19 at 15:07
  • i created a second picturebox that contain the same image as the first picturebox with the difference that the first is zoomed and the second is not (the original pic is bigger than the one show so the normal is actually bigger than the zoomed version) but it only show the upper left corner of the image at this point, how can i refresh in real time the image in the second picturebox to follow the cursor? i thought of using rectangle but then i don't know how to make it talk to the image in the second picturebox. – Matteo Sala Aug 05 '19 at 03:33
  • For this situation you can do this: Make the 2nd pbox Sizemode.AutoSize and nest it in a Panel without scrolbars. Then, upon mousemove in pbox1 change pbox2.Location.. – TaW Aug 05 '19 at 08:46

1 Answers1

1

Here is a simple example with the layout I described in the comment:

  • Both PictureBoxes are nested in Panels.
  • The first one is in Zoom mode and upon loading a file its size is adapted to avoid blank stripes to the sides. Its parent panel is used to reset to the maximum allowed size.
  • The 2nd one is in AutoSize mode and its parent panel is used to 1) hide the outer portions and 2) to calculate the offset to center the image.

Here is the simple Paint event for pbox1:

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    Size sz = pictureBox1.ClientSize;
    Point pt = pictureBox1.PointToClient(Control.MousePosition);
    e.Graphics.DrawLine(Pens.OrangeRed, pt.X, 0, pt.X, sz.Height);
    e.Graphics.DrawLine(Pens.OrangeRed, 0, pt.Y, sz.Width, pt.Y);
}

Here is the MouseMove the triggers the Paint and moves pbox2:

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
    pictureBox1.Invalidate();

    float f = 1f * pictureBox2.ClientSize.Width / pictureBox1.ClientSize.Width;
    Size s2 = pictureBox2.Parent.ClientSize;
    Point p2 = Point.Round(new PointF(s2.Width/2 - e.X * f , s2.Height/2 - e.Y * f ));
    pictureBox2.Location = p2;
}

The file loading is a bit tricky, as it needs to analyze the aspect ratios of image and pbox:

void loadFile(string fileName)
{
    if (File.Exists(fileName))
    {
        pictureBox1.Size = panel1.ClientSize;
        pictureBox1.Location = Point.Empty;

        pictureBox1.Image = Image.FromFile(fileName);
        pictureBox2.Image = Image.FromFile(fileName);
        pictureBox2.Location = Point.Empty;
    }
    Size csz = pictureBox1.ClientSize;
    Size isz = pictureBox1.Image.Size;
    float iar = 1f * isz.Width / isz.Height;  // aspect..
    float car = 1f * csz.Width / csz.Height;  //..ratios
    if (iar < car)
    {
        pictureBox1.ClientSize = new Size((int)(pictureBox1.ClientSize.Height * iar), 
                                          pictureBox1.ClientSize.Height);
    }
    else if (iar > car)
    {
        pictureBox1.ClientSize = new Size((pictureBox1.ClientSize.Width,
                                          (int)(pictureBox1.ClientSize.Width / iar));
    }
}

Note that before loading the new images one should Dispose of the previous images! Also that after setting the pbox2.SizeMode to Autosize one could set it to Zoom and scale its Size up or down to zoom in or out, if one keeps the aspect ratio the same.

Result:

enter image description here

TaW
  • 53,122
  • 8
  • 69
  • 111