将绘制线条图像绘制到Picturebox图像中
在我的表单中,我有2个picturebox
控件.我在pictureBox1
上加载了蓝色背景图像,并单独留下了pictureBox2
控件.使用下面的代码,我可以在picturebox1
图片上方绘制箭头.
In my Form, I have 2 picturebox
controls. I loaded a blue background image on pictureBox1
and left pictureBox2
control alone. With the code below I'm able to draw arrows on top of my picturebox1
image.
目标:在我的pictureBox1_MouseUp
事件中,我想将在pictureBox1
上绘制的所有箭头添加到pictureBox2
.
Goal: On my pictureBox1_MouseUp
event I want to add all the arrows which I drew on pictureBox1
to pictureBox2
.
问题:问题是我写pictureBox2.Image = pictureBox1.Image
时在pictureBox1_MouseUp
事件上发生的,它没有添加我在pictureBox1上绘制的绘制箭头.它只会添加我在表单加载事件中分配的pictureBox1图片.
Issue: The problem is on my pictureBox1_MouseUp
event when I wrote pictureBox2.Image = pictureBox1.Image
it doesn't add the painted arrow which I drew on pictureBox1. It only adds the pictureBox1 image that I assigned in my form load event.
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上绘制箭头,但是看起来它正在绘制多个箭头.
With this code, it draws the arrow on pictureBox2, but it looks like it is drawing multiple arrows.
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 Event上.这占用了太多内存,并且无法在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();
}
}
将所有行绘制到pictureBox1:
Draw all lines to pictureBox1:
仅将最后一行绘制到pictureBox1:
Draw only last line to pictureBox1:
在pictureBox2
控件中,将Paint
事件添加到pictureBox2_Paint
.
In pictureBox2
control, add Paint
event to pictureBox2_Paint
.
我建议您使笔和笔帽全局可变:
I suggest you make pen and cap global varriable:
// 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()
事件中,添加以下行:
In Form1()
event, add this line:
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上的所有线条.
Above code draw lines to PictureBox control, not to image, this allow you remove some lines or clear all lines you draw to picturebox if you want later.
如果您想直接绘制图像,则事情变得容易得多,根本不需要pictureBox2_Paint
:
If you want draw directly to image, things event much easier, you don't need pictureBox2_Paint
at all:
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)
{
}