更新graphics而不删除前一个

我在一个绘图方法中创build了这个

private void draws() { Bitmap bmp = new Bitmap(pictureBox17.Width, pictureBox17.Height); using (Graphics g = Graphics.FromImage(bmp)) { //define area do pictureBox17 e preenche a branco Brush brush = new SolidBrush(Color.White); Rectangle area = new Rectangle(0, 0, pictureBox17.Width, pictureBox17.Height); g.FillRectangle(brush, area); //desenha as linhas do rectangulo g.DrawLine(new Pen(Color.Black), esp, esp, esp, yWcorrigidoesp); // some more lines } pictureBox17.Image = bmp; } 

它正是我想要的。 但想象一下,在此之后,我想更新完全相同的graphics,添加几行,而不必再次画全部,这可能吗? 显然我使用的方法

 draws(); 

然后我想添加一些东西,任何提示?

做到这一点的方法是创build一个DrawAction类,该类包含要绘制的所有数据: Point数据, PenBrush等。

然后你创build并pipe理一个List<DrawAction> drawActions ,然后你有一个select:

  • 您可以通过循环显示列表,在PictureBoxPanel (或任何具有Paint事件的控件)的Paint事件中执行所有绘图。

  • 或者您将新动作添加您正在构build的Bitmap Image中。

有什么更好的确取决于:您是否期望通过用户操作进行dynamic绘图? 你想要一个撤销/重做选项? 然后,在控制面上进行实时绘图更适合。

或者是要修复或从固定数据集派生的事物列表,并且最终将其保存到磁盘。 这听起来更像是绘制到位图中。

两者也可以合并,也许收集一些行动,同时保留撤消选项(通过删除最后的列表项),并提供一个应用button,将他们泵入位图。

注意:绘制东西的关键是将绘图数据准备好在列表中,以便在需要时再使用它,扩展和删除列表,甚至更改它:这将是一个简单的双线程来完成行动和改变PenColorWidthLineStyle或移动Points等等等等!

当您创buildDrawAction类时,如果您可以决定需要哪些操作,将会DrawAction帮助。 如果你还不能,你仍然可以有更多的扩展类,有足够的成员来处理Graphics类提供的所有选项: DrawxxFillxxxPen属性, Colors甚至可以放大。

对于初学者来说,一个Type,一个List<Point>一个float PenWidth和一个Color将会做..

下面是一个简单的类, Paint事件,添加一些testing动作和both代码的例子:

  • 一个button来做现场绘画和..
  • ..一个应用的行动应用到位图ImagePictureBox的行动。

testing数据是一行和一组Polylines

你应该开始改进,通过定义一个Enum所有你想要使用的绘图动作types! 这将更好,更容易理解我编码的廉价字符types;-)types可以包括Rectangle, FilledRectangle, Ellipse, FilledEllipse, Line, Lines, Polygon, FilledPolygon, Text, Curve, Curves ,然后一些。 有了额外的一点,你也可以使用Image,GraphicsPath,Spline等。其他数据可以控制Rotation, Scaling, Gradients, Transparency等。

 List<DrawAction> actions = new List<DrawAction>(); public class DrawAction { public char type { get; set; } // this should be an Enum! public Color color { get; set; } public float penWidth { get; set; } // only one of many Pen properties! public List<Point> points { get; set; } // use PointF for more precision public DrawAction(char type_, Color color_, float penwidth_) { type = type_; color = color_; penWidth = penwidth_; points = new List<Point>(); } } private void pictureBox1_Paint(object sender, PaintEventArgs e) { Draw(e.Graphics, actions); } public void Draw(Graphics G, List<DrawAction> actions) { foreach (DrawAction da in actions) if (da.type == 'L' && da.points.Count > 1) using (Pen pen = new Pen(da.color, da.penWidth)) G.DrawLine(pen, da.points[0], da.points[1]); else if (da.type == 'P' && da.points.Count > 1) using (Pen pen = new Pen(da.color, da.penWidth)) G.DrawLines(pen, da.points.ToArray()); // else.. } private void button1_Click(object sender, EventArgs e) { AddTestActions(); pictureBox1.Invalidate(); } private void button2_Click(object sender, EventArgs e) { AddTestActions(); Bitmap bmp = new Bitmap(pictureBox1.ClientSize.Width, pictureBox1.ClientSize.Height); using (Graphics G = Graphics.FromImage(bmp)) Draw(G, actions); pictureBox1.Image = bmp; } void AddTestActions() { actions.Add(new DrawAction('L', Color.Blue, 3.3f)); actions[0].points.Add(new Point(23, 34)); actions[0].points.Add(new Point(23, 134)); actions.Add(new DrawAction('P', Color.Red, 1.3f)); actions[1].points.Add(new Point(11, 11)); actions[1].points.Add(new Point(55, 11)); actions[1].points.Add(new Point(55, 77)); actions[1].points.Add(new Point(11, 77)); } 

两者的结果看起来一样:

在这里输入图像描述

尝试在函数之外创build位图来保存它,现在你正在做的方式是在函数完成之后处理位图元素。

你可以做一些类似的事情

 Bitmap bmp = new Bitmap(pictureBox17.Width, pictureBox17.Height); private void draws() { if (bmp ==null) using (Graphics g = Graphics.FromImage(bmp)) { //define area do pictureBox17 e preenche a branco Brush brush = new SolidBrush(Color.White); Rectangle area = new Rectangle(0, 0, pictureBox17.Width, pictureBox17.Height); g.FillRectangle(brush, area); //desenha as linhas do rectangulo g.DrawLine(new Pen(Color.Black), esp, esp, esp, yWcorrigidoesp); } else { using (Graphics g = Graphics.FromImage(bmp)) { g.DrawLine(new Pen(Color.Black), esp, esp, esp, yWcorrigidoesp); } // some more lines } pictureBox17.Image = bmp; } 

只是为了让你开始.. 🙂

或者,如果您使用此方法在不同时间绘制多个bmp,则可以将bmp传入绘图函数