Dragging graphics objects on top of bitmaps

2.1k views Asked by At

I am attempting to drag a shape around a picturebox on the mousemove event but am struggling to get it to move smoothly. The picture box has an image loaded as the background and I would like the graphics object to drag a circle on top of the image when the mouse is clicked and dragged.

I have it working by creating a clone of the original image each time the mouse moves and reloading the picture box but it seems like their must be a better way to achieve this.

Without reloading the original bitmap each time any graphics added remain on the image creating a trail which is more like a paint application.

How do I clear previous drawings without reloading the entire image each time? Any help appreciated.

private void picCanvas_MouseMove(object sender, MouseEventArgs e)
{
    if (_drag)
    {
        picCanvas.Image = (Bitmap)_original.Clone();
        Graphics g = Graphics.FromImage((Bitmap)picCanvas.Image);
        g.DrawEllipse(_whitePen, e.X, e.Y, 10, 10);
        picCanvas.Invalidate();
    }
}

private void picCanvas_MouseDown(object sender, MouseEventArgs e)
{
    _drag = true;
}

private void picCanvas_MouseUp(object sender, MouseEventArgs e)
{
    _drag = false;
}
3

There are 3 answers

3
honibis On BEST ANSWER

To solve the problem in the best way, use picCanvas.Paint event. Set the positions at mousemove event and use that positions to draw at paint event.

    Point pos = Point.Empty;// or your initial position

    private void picCanvas_MouseMove(object sender, MouseEventArgs e)
    {
        if (_drag)
        {
            pos = e.Location;
        }
    }
    private void picCanvas_Paint(object sender, PaintEventArgs e)
    {
        if (_drag)
        {
            Graphics g = e.Graphics;//The event handler sends us the graphics object to use for painting
            g.DrawEllipse(_whitePen, pos.X, pos.Y, 10, 10); 
        }
    }

You should add the Paint event to the Control and set the image at formload or some initialization function.

picCanvas.Image = (Bitmap)_original.Clone(); 
0
fluent On

Using the above answer from Honibis I ended up with this.

load in the image and invalidate the picture to cause a refresh

picCanvas.Image = image;
picCanvas.Invalidate()

then in the paint event

private void picCanvas_Paint(object sender, PaintEventArgs e)
{
  if (_drag)         
  {
    using (Pen pen = new Pen(Color.White, 2))
    {
      e.Graphics.DrawEllipse(pen, pos.X, pos.Y, 10, 10);
    }
  }
}
0
HaTiMSuM On

check this sample it is simpler

//Load Image
Bitmap TestImage = new Bitmap(FileName);
//Create Graphics Object
Graphics g = Graphics.FromImage(TestImage);                   
g.DrawEllipse(new Pen(Color.Red), i, j,0.5F, 0.5F);
//View Your Results
pictureBox1.Image = TestImage;