在我的表单中,我有2个picturebox
控件。我在pictureBox1
上加了一个蓝色背景图片,然后单独留下pictureBox2
控件。使用下面的代码,我可以在picturebox1
图片上方绘制箭头。
目标:在我的pictureBox1_MouseUp
活动中,我想将我在pictureBox1
上绘制的所有箭头添加到pictureBox2
。
问题问题发生在pictureBox1_MouseUp
事件中,当我写pictureBox2.Image = pictureBox1.Image
时,它没有添加我在pictureBox1上绘制的绘制箭头。它只添加我在表单加载事件中指定的pictureBox1图像。
private bool isMoving = false;
private Point mouseDownPosition = Point.Empty;
private Point mouseMovePosition = Point.Empty;
private List<Tuple<Point, Point>> lines = new List<Tuple<Point, Point>>();
Pen _Pen;
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (isMoving)
{
if (pictureBox1.Image == null) e.Graphics.Clear(Color.White);
// Add this line for high quality drawing:
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
AdjustableArrowCap bigArrow = new AdjustableArrowCap(5, 5);
_Pen = new Pen(Color.IndianRed, 3);
_Pen.CustomEndCap = bigArrow;
e.Graphics.DrawLine(_Pen, mouseDownPosition, mouseMovePosition);
_Pen.Dispose();
}
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
isMoving = true;
mouseDownPosition = e.Location;
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (isMoving)
{
mouseMovePosition = e.Location;
pictureBox1.Invalidate();
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
if (isMoving)
{
lines.Add(Tuple.Create(mouseDownPosition, mouseMovePosition));
}
isMoving = false;
pictureBox2.Image = pictureBox1.Image;
}
测试1 :(更改了pictureBox1_Paint代码)
使用此代码,它会在pictureBox2上绘制箭头,但看起来它正在绘制多个箭头。
if (isMoving)
{
if (pictureBox1.Image == null) e.Graphics.Clear(Color.White);
// Add this line for high quality drawing:
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
AdjustableArrowCap bigArrow = new AdjustableArrowCap(5, 5);
_Pen = new Pen(Color.IndianRed, 3);
Bitmap BitImg = (Bitmap)pictureBox1.Image;
_Pen.CustomEndCap = bigArrow;
using (var graphics = Graphics.FromImage(BitImg))
{
graphics.DrawLine(_Pen, mouseDownPosition, mouseMovePosition);
}
pictureBox1.Image = BitImg;
_Pen.Dispose();
}
测试2 :(我从paint事件中获取代码并粘贴了MouseMove事件并进行了一些修改。这使用了太多的内存而且它没有在pictureBox1上绘制但箭头现在在pictureBox2中可见)
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (isMoving)
{
mouseMovePosition = e.Location;
if (isMoving)
{
AdjustableArrowCap bigArrow = new AdjustableArrowCap(5, 5);
_Pen = new Pen(Color.IndianRed, 3);
BitImg = new Bitmap(pictureBox1.Image);
_Pen.CustomEndCap = bigArrow;
using (var graphics = Graphics.FromImage(BitImg))
{
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.DrawLine(_Pen, mouseDownPosition, mouseMovePosition);
}
_Pen.Dispose();
}
pictureBox1.Invalidate();
}
}
答案 0 :(得分:1)
这里有两个问题:
您在Control上绘制而不是在图像上绘制。图像保持不变。
pictureBox1
和pictureBox2
都指的是同一张图片。更改图像时,下一个绘制事件将影响两个控件。
因此,在pictureBox1_Paint
中,您需要创建pictureBox1.Image
的副本(尝试使用Bitmap
),然后在其上绘制并将更新的图像分配给pictureBox1.Image
。它会自动绘制。
答案 1 :(得分:1)
在pictureBox2
控件中,将Paint
事件添加到pictureBox2_Paint
。
我建议你让笔和帽全局变化:
// Make pen and cap global varriable to boost the perfomane.
// Create and delete them each draw will cost alot of CPU
Pen pen = new Pen(Color.IndianRed, 3);
AdjustableArrowCap bigArrow = new AdjustableArrowCap(5, 5);
在Form1()
事件中,添加以下行:
pen.CustomEndCap = bigArrow;
并执行以下操作:
public partial class Form1 : Form
{
private bool isMoving = false;
private Point mouseDownPosition = Point.Empty;
private Point mouseMovePosition = Point.Empty;
private List<Tuple<Point, Point>> lines = new List<Tuple<Point, Point>>();
public Form1()
{
InitializeComponent();
pen.CustomEndCap = bigArrow;
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
isMoving = true;
mouseDownPosition = e.Location;
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (isMoving)
{
mouseMovePosition = e.Location;
pictureBox1.Invalidate();
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
if (isMoving)
{
lines.Add(Tuple.Create(mouseDownPosition, mouseMovePosition));
pictureBox2.Invalidate();
}
isMoving = false;
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (isMoving)
{
if ((sender as PictureBox).Image == null) e.Graphics.Clear(Color.White);
// Add this line for high quality drawing:
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
e.Graphics.DrawLine(pen, mouseDownPosition, mouseMovePosition);
// If you want draw all previous lines here, add bellow code:
//foreach (var line in lines)
//{
// e.Graphics.DrawLine(pen, line.Item1, line.Item2);
//}
}
}
private void pictureBox2_Paint(object sender, PaintEventArgs e)
{
if ((sender as PictureBox).Image == null) e.Graphics.Clear(Color.White);
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
foreach (var line in lines)
{
e.Graphics.DrawLine(pen, line.Item1, line.Item2);
}
}
}
上面的代码画线到PictureBox控件,而不是图像,这允许你删除一些行或清除你绘制到picturebox的所有行,如果你想在以后。
如果您想直接绘制图像,事情更容易,您根本不需要pictureBox2_Paint
:
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
if (isMoving)
{
// You event don't need this line
//lines.Add(Tuple.Create(mouseDownPosition, mouseMovePosition));
if (pictureBox1.Image != null)
{
using (var g = Graphics.FromImage(pictureBox1.Image))
{
g.SmoothingMode = SmoothingMode.HighQuality;
g.DrawLine(pen, mouseDownPosition, mouseMovePosition);
}
pictureBox2.Image = pictureBox1.Image;
}
}
isMoving = false;
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (isMoving)
{
if ((sender as PictureBox).Image == null) e.Graphics.Clear(Color.White);
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
e.Graphics.DrawLine(pen, mouseDownPosition, mouseMovePosition);
}
}
private void pictureBox2_Paint(object sender, PaintEventArgs e)
{
}