将画线图像绘制到图片框图像中
Paint Drawline Image into Picturebox Image
在我的表单中,我有 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:(我从绘画事件中取出代码并粘贴了一些修改的 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();
}
}
你这里有两个问题:
您在控件而不是图像上作画。图片保持不变
pictureBox1
和 pictureBox2
指的是同一张图片。当您更改图像时,两个控件都将在下一个绘制事件中受到影响。
因此,在 pictureBox1_Paint
中,您需要创建 pictureBox1.Image
的副本(尝试使用 Bitmap
),然后在其上绘画并将更新后的图像分配给 pictureBox1.Image
。会自动上色
将所有线条绘制到 pictureBox1:
只绘制 pictureBox1 的最后一行:
在pictureBox2
控件中,添加Paint
事件到pictureBox2_Paint
。
我建议你将 pen 和 cap 设为全局变量:
// 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 控件,而不是图像,如果您以后需要,这允许您删除一些线条或清除绘制到图片框的所有线条。
如果你想直接绘制到图像上,事情就容易多了,你根本不需要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)
{
}
在我的表单中,我有 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:(我从绘画事件中取出代码并粘贴了一些修改的 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();
}
}
你这里有两个问题:
您在控件而不是图像上作画。图片保持不变
pictureBox1
和pictureBox2
指的是同一张图片。当您更改图像时,两个控件都将在下一个绘制事件中受到影响。
因此,在 pictureBox1_Paint
中,您需要创建 pictureBox1.Image
的副本(尝试使用 Bitmap
),然后在其上绘画并将更新后的图像分配给 pictureBox1.Image
。会自动上色
将所有线条绘制到 pictureBox1:
只绘制 pictureBox1 的最后一行:
在pictureBox2
控件中,添加Paint
事件到pictureBox2_Paint
。
我建议你将 pen 和 cap 设为全局变量:
// 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 控件,而不是图像,如果您以后需要,这允许您删除一些线条或清除绘制到图片框的所有线条。
如果你想直接绘制到图像上,事情就容易多了,你根本不需要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)
{
}