Search code examples
graphicsbitmapmouseeventmousedownmouseup

Draw Graphics on bitmap


I try to use mouse up and mouse down to draw rectangles on bitmaps. But the problem is that the rectangle always delay one event. For example, I try to draw a rectangle (0,0,50,50) in the first time but there is no rectangle drawing on bitmap. I continues drawing a rect (50,50,100,100) but a rect (0,0,50,50) created (not be the rect (50,50,100,100). If I keep to draw next rects, it always delay like that. Please help me! This is my code:

Rectangle rect = new Rectangle(0, 0, 0, 0);
int Xmouse;
int Ymouse;
public Form1()
{
    InitializeComponent();
    pictureBox1.Paint += new PaintEventHandler(pictureBox1_Paint);
      this.DoubleBuffered = true;
}

private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
    Xmouse = e.X;
    Ymouse = e.Y;
    drawOK = true;
}

private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
    if (drawOK)
    {
        drawOK = false;
        rect = new Rectangle(Xmouse * 3676 / 800, Ymouse * 3676 / 800, (e.X - Xmouse) * 3676 / 800, (e.Y - Ymouse) * 3676 / 800);
        pictureBox1.Invalidate();
    }

}


private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    using (var g = Graphics.FromImage(pictureBox1.Image))
    {
        using (Pen myPen = new Pen(Color.Black, 6))
        {
            g.DrawRectangle(myPen, rect);
        }
    }

}

Solution

  • Try moving your draw method outside of paint into a different sub and call that sub manually from mouse up:

    Rectangle rect = new Rectangle(0, 0, 0, 0);
    int Xmouse;
    int Ymouse;
    bool drawOK;
    private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
    {
        Xmouse = e.X;
        Ymouse = e.Y;
        Console.WriteLine("MouseDown({0},{1})", e.X, e.Y);
        drawOK = true;
    }
    
    private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
    {
        if (drawOK)
        {
            drawOK = false;
            Console.WriteLine("MouseUp({0},{1})", e.X, e.Y);
            rect = new Rectangle(Xmouse , Ymouse , (e.X - Xmouse) , (e.Y - Ymouse) );
            DrawRect();
            pictureBox1.Invalidate();
        }
    }
    
    private void DrawRect()
    {
        Console.WriteLine("drawing {0}", rect);
        using (var g = Graphics.FromImage(pictureBox1.Image))
        {
            using (Pen myPen = new Pen(Color.Black, 6))
            {
                g.DrawRectangle(myPen, rect);
            }
        }
    }
    
    private void ClearPic()
    {
        using (var g = Graphics.FromImage(pictureBox1.Image))
        {
            using (Brush myPen = Brushes.White)
            {
                g.Clear(Color.White);                 
            }
        }
    }
    
    private void Form1_Load(object sender, EventArgs e)
    {
        Image bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
        pictureBox1.Image = bmp;
        ClearPic();
        pictureBox1.Paint += new PaintEventHandler(pictureBox1_Paint);
        pictureBox1.MouseDown += pictureBox1_MouseDown;
        pictureBox1.MouseUp += pictureBox1_MouseUp;
    }