【问题标题】:zoom an image in a second picturebox following cursor在光标后的第二个图片框中缩放图像
【发布时间】:2019-12-12 07:15:49
【问题描述】:

我有一个包含图像 (1280 X 720) 的图片框,我想创建第二个图片框,其中包含以光标为中心的图像的缩放版本(例如,光标周围的 40 X 40 正方形缩放为在一个 120 X 120 的方形图片框中)实时跟随光标(如果图片框中间也可以有一个十字来显示光标的精确放置就更好了)。

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;

     }

【问题讨论】:

  • - 提示:您可以在设置缩放因子后在类级别创建放大的位图。然后对 pbox2.MouseMove 事件进行编码。它可以显示缩放位图的一部分。要创建您将使用 Bitmap(Image, Size) 构造函数。您可以使用 pbox2.Paint 事件使用 e.Graphics.DrawImage 方法绘制一个矩形,该方法带有两个矩形。对于十字准线光标,您可以使用 pbox1.Paint 和 2 个 DrawLine 调用。要找到源矩形,您需要使用缩放因子进行计算。
  • 使用类似的技术,您也可以在原始 pbox 上绘制并丢弃 pbox2..
  • 我创建了第二个图片框,其中包含与第一个图片框相同的图像,不同之处在于第一个是缩放的,第二个不是(原始图片比显示的大,所以正常情况实际上是比放大版大)但此时只显示图像的左上角,如何实时刷新第二个图片框中的图像以跟随光标?我想过使用矩形,但后来我不知道如何让它与第二个图片框中的图像对话。
  • 对于这种情况,您可以这样做:制作第二个 pbox Sizemode.AutoSize 并将其嵌套在没有滚动条的面板中。然后,在 pbox1 中的 mousemove 更改 pbox2.Location..

标签: c# image zooming picturebox


【解决方案1】:

这是我在评论中描述的布局的一个简单示例:

  • 两个图片框都嵌套在面板中。
  • 第一个是Zoom 模式,在加载文件时,它的大小会调整以避免两侧出现空白条纹。其父面板用于重置为允许的最大尺寸。
  • 第二个处于AutoSize 模式,其父面板用于 1) 隐藏外部部分和 2) 计算偏移以使图像居中。

这是 pbox1 的简单 Paint 事件:

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);
}

这里是MouseMove,触发Paint并移动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;
}

文件加载有点棘手,因为它需要分析图像和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));
    }
}

请注意,在加载新图像之前,应该Dispose 之前的图像!此外,pbox2.SizeMode 设置为Autosize 之后,可以将其设置为Zoom 并向上或向下缩放其Size 以放大或缩小,如果保持纵横比相同的话.

结果:

【讨论】:

    猜你喜欢
    • 2015-12-30
    • 2012-09-20
    • 2012-10-21
    • 2018-07-30
    • 2016-10-31
    • 1970-01-01
    • 1970-01-01
    • 2013-07-14
    相关资源
    最近更新 更多