Draw on a bitmap in C#

[example]

This example shows how you can draw on a bitmap and display the result on a form. The example Draw in a Paint event handler in C# shows how to draw in a form’s Paint event handler. This is simple, but the Paint event is raised every time the form grows larger or is covered and then exposed. If the drawing takes a long time, then the event handler can take a little while and the user may notice.

This example shows how to draw on a Bitmap once when the form loads. There are two basic approaches for displaying the result.

First you can set the form’s BackgroundImage property equal to the bitmap. Then you can use the BackgroundImageLayout property to determine how the image is arranged. This property can take the following values:

  • None—The image is displayed in the form’s upper left corner.
  • Tile—The image is repeated as needed to cover the form.
  • Center—The image is centered if it fits. If the form is too small vertically or horizontally, it is aligned on the corresponding edge.
  • Stretch—The image is stretched to fill the form, distorting it if necessary.
  • Zoom—The image is made as large as possible while still fitting within the form and not stretching it out of shape.

This method is useful if you want one of those arrangement strategies.

A second approach is to display the image in a PictureBox control’s Image property. That control’s SizeMode property is similar to the form’s BackgroundImageLayout property. It takes the following values:

  • Normal—The image is displayed in the control’s upper left corner.
  • StretchImage—The image is stretched to fill the control, distorting it if necessary.
  • AutoSize—The control is resized to fit the image.
  • CenterImage—The image is centered. (If the control is too small, the image is still centered.)
  • Zoom—The image is made as large as possible while still fitting within the control and not stretching it out of shape.

(Yes, it’s silly that the BackgroundImageLayout and SizeMode properties don’t have the same values and behaviors.)

This example sets a PictureBox control’s Image property to the bitmap. The PictureBox automatically re-displays the image whenever necessary without requiring any drawing code in a Paint event handler.

The following code shows how the example draws its picture.

// Make and display a Bitmap.
private void Form1_Load(object sender, EventArgs e)
{
    picDrawing.SizeMode = PictureBoxSizeMode.AutoSize;
    picDrawing.Location = new Point(0, 0);

    Bitmap bm = new Bitmap(280, 110);
    using (Graphics gr = Graphics.FromImage(bm))
    {
        gr.SmoothingMode = SmoothingMode.AntiAlias;

        Rectangle rect = new Rectangle(10, 10, 260, 90);
        gr.FillEllipse(Brushes.LightGreen, rect);
        using (Pen thick_pen = new Pen(Color.Blue, 5))
        {
            gr.DrawEllipse(thick_pen, rect);
        }
    }

    picDrawing.Image = bm;
}

First the code prepares its PictureBox by setting SizeMode = AutoSize and moving the PictureBox into the form’s upper left corner. (You could do this at design time but I wanted to the code emphasize the fact that SizeMode = AutoSize. That guarantees that the Bitmap is completely visible in the control.)

Next the program makes a Bitmap and a Graphics object to draw on it.

The code sets the Graphics object’s SmoothingMode property to get smooth drawing. It creates a Rectangle to define the ellipse, fills the ellipse, and then outlines it with a thick pen.

After all of the drawing, the code sets the PictureBox control’s Image property to the Bitmap.


Download Example   Follow me on Twitter   RSS feed   Donate




This entry was posted in drawing, graphics and tagged , , , , , , , , , , , . Bookmark the permalink.

4 Responses to Draw on a bitmap in C#

  1. Pingback: Draw smooth graphics in C# - C# HelperC# Helper

  2. Sairah says:

    Hi Mr.Rod
    I am drawing graphics on an image. The problem which I am facing that when data Read thread begins the graphics starts plotting on an image in a PictureBox.

    I want when the data thread stops the graphics (Draw.Image(..)) disappears (or erased) and then reappear when the “Data_Read” thread resume.
    please tell me how I can do it?

    I am sharing the block of my code.

    bool draw;
    
    private void Form1_Load(object sender, EventArgs e)
    {
        pictureBox1.Image = new Bitmap(“Image.jpg”);
        Thread DataRead = new Thread (Data_Read);
        DataRead.Start();
    }
    public void DataRead()
    {
        //Body of for data reading//;
        if (data_read !=null)
        {
            draw = true;
        }
        else
        {
            draw = false;
        }
    }
    private void picbox_paint(object sender, PaintEventArgs e)
    {
        if (draw == true)
        {
            e.Graphics.DrawImage(new Bitmap(“img.png”), x, y, 16, 16);
        }
        else
        {
            // // what should I do in this part?
        }
        e.Dispose(); pictureBox1.invalidate();
    }
    • RodStephens says:

      I’m not sure I understand, but maybe this will help.

      First, you shouldn’t use Invalidate inside the Paint event handler. That will make it redraw which will call Paint again an you’ll get a sort of infinite loop. And you shouldn’t dispose the parameter to Paint.

      I think you need the thread’s code to erase the image when it starts (or have the code that starts it do that) and then stop the drawing when it is about to finish. It cannot directly manipulate the PictureBox because it’s on another thread, so it needs to call Invoke to make another method do that.

      Alternatively you could consider using a BackgroundWorker instead of a thread. BackgroundWorker’s are generally easier to use.

      I hope that helps. If it doesn’t can you say a bit more about what you’re trying to do when the thread is running and when it is stopped? I don’t think I understand that part completely.

      • Sairah says:

        Thank you, Mr. Rod, for your reply…
        I am sorry not to be clear in the beginning… I hope now you understand.
        In my actual case, I am receiving the data stream continuously from the UDP client to UI panel (UDP server).
        when the UI panel started to receive the data stream. the graphics started plotting.
        I want when UDP client stops sending data stream the graphics object should disappear.

        In actual its this:

        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
                
            Double w, x;
            Graphics path;
            bool draw;
               
            private void Form1_Load(object sender, EventArgs e)
            {
                pictureBox1.Image = new Bitmap("Map_Image.jpg");
                pictureBox1.BorderStyle = BorderStyle.FixedSingle;
                draw = false;
                Thread UDP = new Thread(new ThreadStart(UDP_Server));
                UDP.Start();
            }
            public void UDP_Server()
            {
                UdpClient UdpServer = new UdpClient(3000);
                IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
                while (true)
                {
                    Byte[] data = UdpServer.Receive(ref sender);
                    String line = Encoding.ASCII.GetString(data);
                    var part = line.Split('\t');
        
                    if (Double.Parse(part[0]) == 1)
                    {
                        w = (Double.Parse(part[1]);
                        x = (Double.Parse(part[2]);
                    }
                    if (data != null)
                    {
                        draw = true;
                    }
                    else
                    {
                        draw = false;
                    }
                }
            }   
            
            private void PictureBox_Paint(object sender, PaintEventArgs e)
            {
                if (draw == true)
                {
                    e.Graphics.DrawImage(new Bitmap("img1.png"), Convert.ToInt32(x), Convert.ToInt32(w), 18, 25);
                }
                else
                {
                    // I need help here
                }
                e.Dispose();
                pictureBox1.Invalidate();
            }
        }

Leave a Reply

Your email address will not be published. Required fields are marked *