Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在图片框内绘制矩形大小模式缩放_C#_Winforms_Zooming_Picturebox - Fatal编程技术网

C# 在图片框内绘制矩形大小模式缩放

C# 在图片框内绘制矩形大小模式缩放,c#,winforms,zooming,picturebox,C#,Winforms,Zooming,Picturebox,我在WindowsForms项目中有一个图片框,其SizeMode为“缩放” 我想在图像中画一个矩形,得到它相对于图像而不是图片框的坐标 问题是矩形的坐标与Windows Paint应用程序上选择的相同矩形不匹配。 以下是使用的代码: 开始喷漆: /// <summary> /// Starts drawing. /// </summary> /// <param name="sender"></param> /// <param name=

我在WindowsForms项目中有一个图片框,其SizeMode为“缩放”

我想在图像中画一个矩形,得到它相对于图像而不是图片框的坐标

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

以下是使用的代码:

  • 开始喷漆:

    /// <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();
    }
    
    //
    ///开始画画。
    /// 
    /// 
    /// 
    私有void pictureBox1\u MouseDown(对象发送方,MouseEventArgs e)
    {
    backupImage=pictureBox1.Image;
    _一次=真;
    RectStartPoint=e.位置;
    pictureBox1.Invalidate();
    }
    
  • 移动鼠标时:

    /// <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);
        }
    }
    
    //
    ///移动鼠标事件时,绘制矩形
    /// 
    /// 
    /// 
    私有void pictureBox1\u MouseMove(对象发送方,MouseEventArgs e)
    {
    if(_once)//仅在绘图模式下绘制矩形
    {
    点端点=e.位置;
    Rect.Location=新点(Math.Min(RectStartPoint.X,tempEndPoint.X),
    Min(RectStartPoint.Y,tempEndPoint.Y));
    Rect=新矩形(
    Math.Min(tempEndPoint.X,矩形左),
    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(裁剪,矩形);
    }
    }
    
  • 当2次单击时,发现其绘制矩形:

    /// <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;
            }
        }
    }
    
    //
    ///释放鼠标单击时,在文本框中写入矩形的坐标。
    /// 
    /// 
    /// 
    私有无效图片box1u MouseUp(对象发送器,MouseEventArgs e)
    {
    如果(一次)
    {
    if(e.Button==System.Windows.Forms.MouseButtons.Left)
    {
    点端点=e.位置;
    _一次=假;
    string sAux=string.Format(“左:{0};顶:{1};宽:{2};高:{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映像

    绘画图像

    正如您在两幅图像上看到的,左侧、顶部、宽度和高度不匹配

    你能告诉我如何得到同样的结果吗


    这里有一个函数可以帮助您进行各种计算:

    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);
        }
    }
    
    下面是如何使用它,给定一个从鼠标坐标创建的
    矩形Rect

    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();
    
    无论图像是横向的还是纵向的,或者图像或图片盒的比率(如果有)更大,这都应该有效

    请注意,随着图像的强烈缩放,很难进行像素效果选择


    该函数是中函数的变体。

    您需要计算缩放,然后将其应用于矩形
    float zoom=1f*PBox.Image.Width/PBox.ClientSize.Width
    Hi TaW,谢谢您的回答。它不起作用,因为当我开始绘制矩形时,坐标是相对于picturebox的,而不是相对于图像的,所以为了保持纵横比,在这种情况下,picturebox的高度大于图像高度。不确定这有什么关系。请注意,如果您有emtpy区域(是吗?),即如果image和pbox的比率不相同,则需要计算并使用其中一个链接中所示的imagearea。然后缩放矩形的所有数字。-要检查,我们需要知道PBox的ClientSize。我编辑了我的第一篇文章,添加了另一个示例图像。在本例中,我检索以下值:Left:5;排名前38名;宽度:870;身高:196。如您所见,矩形的顶行位于图像开始(0,0)上方。您是否根据链接中的SetImageScale函数计算了ImgArea?它应该是计算的基础。。