在图片框内绘制矩形SizeMode缩放 [英] Draw Rectangle inside picture box SizeMode Zoom

查看:137
本文介绍了在图片框内绘制矩形SizeMode缩放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在WindowsForms项目中有一个图片框,其SizeMode为"Zoom".

I have a picture box in a WindowsForms project with its SizeMode to "Zoom".

我想在图像内部绘制一个矩形,并获取其相对于图像而不是图片框的坐标.

I want to draw a rectangle inside image and get its coordinates relative to the image and not to the picture box.

问题是该矩形的坐标与Windows Paint应用程序上选择的同一矩形不匹配.

以下是使用的代码:

  1. 开始绘画:

  1. Start Painting:

/// <summary>
/// Starts drawing.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
    backupImage = pictureBox1.Image;
    _once = true;
    RectStartPoint = e.Location;
    pictureBox1.Invalidate();
}

  • 移动鼠标时:

  • While moving mouse:

    /// <summary>
    /// While moving mouse event, paint rectangle
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
        if (_once) //Only draw rectangle while drawing mode
        {
            Point tempEndPoint = e.Location;
            Rect.Location = new Point(Math.Min(RectStartPoint.X, tempEndPoint.X),
                Math.Min(RectStartPoint.Y, tempEndPoint.Y));
    
            Rect = new Rectangle(
                Math.Min(tempEndPoint.X, Rect.Left),
                Math.Min(tempEndPoint.Y, Rect.Top),
                Math.Min(e.X - RectStartPoint.X, pictureBox1.ClientRectangle.Width - RectStartPoint.X),
                Math.Min(e.Y - RectStartPoint.Y, pictureBox1.ClientRectangle.Height - RectStartPoint.Y));
    
            pictureBox1.Refresh();
            pictureBox1.CreateGraphics().DrawRectangle(cropPen, Rect);
        }
    }
    

  • 单击2次,完成绘画矩形:

  • When 2 click, finhish painting rectange:

    /// <summary>
    /// When mouse click is released, write in texbox the rectangle's coordinates.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
    {
        if (_once)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                Point tempEndPoint = e.Location;
    
                _once = false;
                string sAux = string.Format("Left: {0}; Top: {1}; Width: {2}; Height: {3} \r\n", Math.Min(tempEndPoint.X, Rect.Left), Math.Min(tempEndPoint.Y, Rect.Top),
                        Math.Min(e.X - RectStartPoint.X, pictureBox1.ClientRectangle.Width - RectStartPoint.X), Math.Min(e.Y - RectStartPoint.Y, pictureBox1.ClientRectangle.Height - RectStartPoint.Y));
    
                textBox1.Text += sAux;
            }
        }
    }
    

  • 结果是:

    Windows映像

    Windows Image

    绘画图片

    正如您在两个图像上看到的那样,左,上,宽和高都不匹配.

    As you can see on both images, left, top, width and height do not match.

    您能告诉我如何获得相同的结果吗?

    Can you tell me how to obtain the same result?

    Example2

    推荐答案

    这是一个有助于进行各种计算的函数:

    Here is a function to help with various calculations:

    void SetImageScale(PictureBox pbox, out RectangleF ImgArea , out float zoom)
    {
        SizeF sp = pbox.ClientSize;
        SizeF si = pbox.Image.Size;
        float rp = sp.Width / sp.Height;   // calculate the ratios of
        float ri = si.Width / si.Height;   // pbox and image
    
        if (rp > ri)
        {
            zoom = 1f * sp.Height / si.Height;
            float width = si.Width * zoom;
            float left = (sp.Width - width) / 2;
            ImgArea = new RectangleF(left, 0, width, sp.Height);
        }
        else
        {
            zoom = 1f * sp.Width / si.Width;
            float height = si.Height * zoom;
            float top = (sp.Height - height) / 2;
            ImgArea = new RectangleF(0, top, sp.Width, height);
        }
    }
    

    在给定根据鼠标坐标创建的Rectangle Rect的情况下,这里是如何使用它的方法:

    Here is how you can use it, given a Rectangle Rect which you created from the mouse coordinates:

    float zoom = 1f;
    RectangleF ImgArea = Rectangle.Empty;
    
    SetImageScale(pictureBox1, out ImgArea, out zoom);
    
    Point RLoc = Point.Round(new PointF( (Rect.X - ImgArea.X) / zoom, 
                                         (Rect.Y - ImgArea.Y) / zoom ));
    Size RSz = Size.Round(new SizeF(Rect.Width / zoom, Rect.Height / zoom));
    
    label1.Text =  "Selection in mouse coordinates: "  + Rect.ToString();
    label2.Text =  "Selection in image coordinates: "  + new Rectangle(RLoc, RSz).ToString();
    

    无论图像是横向还是纵向,或者图像或PictureBox的比例更大,这都应该起作用.

    This should work no matter whether the images are landscape or portrait or which ratio if any is greater, the Image's or the PictureBox's.

    请注意,随着图像的高度缩放,很难进行像素完美的选择.

    Note that with the images strongly zoomed it is hard to do a pixel-pefect selection..

    此功能是此帖子中的功能的变体.

    The function is variant of the one in this post.

    这篇关于在图片框内绘制矩形SizeMode缩放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆