Search code examples
c#pictureboxsystem.drawingimagingdrawellipse

Dragging graphics objects on top of bitmaps


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;
}

Solution

  • 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();