首页 > 解决方案 > zoom an image in a second picturebox following cursor

问题描述

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;

     }

标签: c#imagezoomingpicturebox

解决方案


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


推荐阅读