I created this within a drawing method
private void draws()
{
Bitmap bmp = new Bitmap(pictureBox17.Width, pictureBox17.Height);
using (Graphics g = Graphic
Try creating the Bitmap outside of the function to preserve it, the way you are doing it now disposes of the Bitmap element after the function has completed.
you could then do something like
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;
}
Just to get you started.. :)
Alternatively you can pass the bmp into the draw function if you use this method to draw multiple bmp at different times
The way to do it is to create a DrawAction
class which holds all the data needed for the things you want to draw: The Point
data, the Pen
or Brush
etc.
Then you create and manage a List<DrawAction> drawActions
and then you have a choice:
You either do all the drawing 'live' in the Paint
event of the PictureBox
or a Panel
(or any control with a Paint
event) by looping over the list..
..Or you add the new Actions into the Bitmap Image
you are building up.
What is better really depends: do you expect to do dynamic drawing, say by user actions? Do you want an undo/redo option? Then live drawing onto the control surface is a little better suited.
Or is the list of things to do fixed or derive from a fixed set of data and meant to be eventually saved to disk. That sounds more like drawing into the bitmap.
Both can also be combined, maybe collect a number of actions while keeping the option of undoing (by removing the last list item) and offering an Apply button to pump them into the bitmap..
Note: The key to drawing stuff is to keep the drawing data ready in a list so you can use it when you need it again, expand and delete the list and even change it: It would be a simple two-liner to go over all the actions and to change the Color
or the Width
or the LineStyle
of the Pen
or shifting Points
a little etc etc!
When you create the DrawAction
class it helps if you can decide which actions you will need. If you can't you still can go for a more extended class with enough members to work with all the many options the Graphics
class offers: Drawxx
, Fillxxx
, Pen
properties, Colors
maybe even zoom..
For starters a Type, a List<Point>
a float PenWidth
and a Color
will do..
Here is an example with a simple class, the Paint
event, code to add a few test actions and both
:
Image
of a PictureBox
. The test data are one Line
and one set of Polylines
.
You should start improving on it by defining an Enum
with all the types of drawing actions you want to use! This will be much better and easier to understand the the cheapo character type I have coded ;-) The types could include Rectangle, FilledRectangle, Ellipse, FilledEllipse, Line, Lines, Polygon, FilledPolygon, Text, Curve, Curves
and then some. With a little extra you can also work with Image, GraphicsPath, Spline.. And other data could control Rotation, Scaling, Gradients, Transparency
etc..
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));
}
The result for both looks the same: