放大后删除绘制的矩形缩放框
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();
}
起初我以为你需要这个:
- 这是非常罕见的情况之一,您的绘画应该不在
Paint
事件中完成,但在MouseMove
使用由 CreateGraphics
. 创建的 Graphics
对象
之所以这里是正确的方法,是因为对于这种交互式橡皮筋绘图,你不希望绘图坚持。其他示例是 行预览 或 光标交叉 。
要使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);
}
}
总结一下:除了很多细节之外,您的主要问题是在绘画事件中缺少对鼠标按钮的检查..
我正在尝试编写一个透明的可拖动矩形缩放框,一旦鼠标再次抬起,它就会放大到该区域并删除绘制的矩形。
我已经可以使用缩放并绘制矩形,但是我不能 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();
}
起初我以为你需要这个:
- 这是非常罕见的情况之一,您的绘画应该不在
Paint
事件中完成,但在MouseMove
使用由CreateGraphics
. 创建的
Graphics
对象
之所以这里是正确的方法,是因为对于这种交互式橡皮筋绘图,你不希望绘图坚持。其他示例是 行预览 或 光标交叉 。
要使
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);
}
}
总结一下:除了很多细节之外,您的主要问题是在绘画事件中缺少对鼠标按钮的检查..