放大后删除绘制的矩形缩放框

Deleting drawn rectangle zoom box after zooming in

我正在尝试编写一个透明的可拖动矩形缩放框,一旦鼠标再次抬起,它就会放大到该区域并删除绘制的矩形。

我已经可以使用缩放并绘制矩形,但是我不能 1) 弄清楚如何使其透明,以及 2) 弄清楚如何在放大后删除矩形。一旦单击鼠标在放大的图像上绘制另一个缩放框(我正在绘制分形),它就会再次被删除,但我不知道在放大后要删除它要写什么。

绘画

private void Form1_Paint(object sender, PaintEventArgs e)
        {                
            Graphics windowG = e.Graphics;
            windowG.DrawImageUnscaled(picture, 0, 0);
            if (rectangle == true)
            {
               e.Graphics.FillRectangle(Brushes.Aquamarine, rec);
            }
            if (rectangle == false)
            {
                Invalidate();
            }


        }

鼠标按下

                rectangle = true;
                if (e.Button == MouseButtons.Left)
                {
                    rec = new Rectangle(e.X, e.Y, 0, 0);
                    Invalidate();
                }

鼠标抬起

{
    rectangle = false;
}

鼠标移动

if (e.Button == MouseButtons.Left)
                {
                    rec.Width = e.X - rec.X;
                    rec.Height = e.Y - rec.Y;
                    Invalidate();
                }

起初我以为你需要这个:

  1. 这是非常罕见的情况之一,您的绘画应该Paint事件中完成,但在MouseMove 使用由 CreateGraphics.
  2. 创建的 Graphics 对象

之所以这里是正确的方法,是因为对于这种交互式橡皮筋绘图,你希望绘图坚持。其他示例是 行预览 光标交叉

  1. 要使Rectangle透明,您可以

    • 使用DrawRectangle
    • 或使用半透明颜色和FillRectangle
    • 或在下面的示例中同时使用两者:

这是您需要的代码:

Point mDown = Point.Empty;

private void Form1_MouseDown(object sender, MouseEventArgs e)
{
    mDown = e.Location;  // note the first corner
}

private void Form1_MouseUp(object sender, MouseEventArgs e)
{
    Invalidate();   // clear the rectangle
}

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == System.Windows.Forms.MouseButtons.Left)
    using (Graphics G = this.CreateGraphics() ) // !!! usually wrong !!!
    {
        G.Clear(BackColor); // Invalidate();
        Rectangle rect = rectangle(mDown, e.Location);
        // either
        using (SolidBrush brush = new SolidBrush(Color.FromArgb(32, 255, 0, 0)))
            G.FillRectangle(brush, rect);
        // or
        G.DrawRectangle(Pens.Red, rect);
    }
}

此功能可让您开始绘制任意角,而不仅仅是左上角:

Rectangle rectangle (Point p1, Point p2)
{
    int x = Math.Min(p1.X, p2.X);
    int y = Math.Min(p1.Y, p2.Y);
    int w = Math.Abs(p1.X - p2.X);
    int h = Math.Abs(p1.Y - p2.Y);
    return new Rectangle(x, y, w, h);
}

请注意,如果您有 BackgroundImage,则上述代码将无法正常工作。

不过现在我觉得这更接近你的情况:

在这种情况下,我们返回正常方式并在 Paint 中绘制内容,但只要按下鼠标按钮即可。由于我们这里没有鼠标参数,我们需要另一个 class 级别 Point 并且还使用 Control.MouseButtons 属性:

Point mCurrent = Point.Empty;

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
    mCurrent = e.Location;
    Invalidate();
}

private void Form1_MouseUp(object sender, MouseEventArgs e)
{
    mDown = Point.Empty;
    mCurrent = Point.Empty;
    Invalidate();
}

private void Form1_Paint(object sender, PaintEventArgs e)
{
    if (Control.MouseButtons == System.Windows.Forms.MouseButtons.Left)
    {
        Rectangle rect = rectangle(mDown, mCurrent);
        // either one..
        using (SolidBrush brush = new SolidBrush(Color.FromArgb(32, 255, 0, 0)))
            e.Graphics.FillRectangle(brush, rect);
        // ..or both of these
        e.Graphics.DrawRectangle(Pens.Red, rect);
    }

}

总结一下:除了很多细节之外,您的主要问题是在绘画事件中缺少对鼠标按钮的检查..