Search code examples
c#.netwinformssystem.drawing

How to select an area on a PictureBox.Image with mouse in C#


i just wanted to put a selection on my picturebox.image but this has just become worse than some little annoying situation. I thought on another picture box over the main picturebox but it seemed so lazy work to me. I need to know if there is a way to create a selection area (which is gonna be half transparent blue area) on a picturebox.image which im gonna draw with mouse and it shouldnt change the image im working on.

sample:

    // Start Rectangle
    //
    private void pictureBox1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
    {
        // Determine the initial rectangle coordinates...
        RectStartPoint = e.Location;
        Invalidate();
    }

    // Draw Rectangle
    //
    private void pictureBox1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
    {
        if (e.Button != MouseButtons.Left)
            return;
        Point tempEndPoint = e.Location;
        Rect =
            new Rectangle(
                Math.Min(RectStartPoint.X, tempEndPoint.X),
                Math.Min(RectStartPoint.Y, tempEndPoint.Y),
                Math.Abs(RectStartPoint.X - tempEndPoint.X),
                Math.Abs(RectStartPoint.Y - tempEndPoint.Y));
        Invalidate(Rect);
    }

    // Draw Area
    //
    private void pictureBox1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
    {
        // Draw the rectangle...
        if (pictureBox1.Image != null)
        {
            Brush brush = new SolidBrush(Color.FromArgb(128, 72, 145, 220));
            e.Graphics.FillRectangle(brush, Rect);
        }
    }

Solution

  • I used your code, you were nearly there. You needed to Invalidate the pictureBox1 instead of the rectangle. I also added a check for the Rect so it doesn't get drawn when it's not initialized or has no size.

    Another important change: I created the Rectangle only once and I adjusted its location and size. Less garbage to clean up!

    EDIT

    I added a mouse right-click handler for the Rectangle.

    private Point RectStartPoint;
    private Rectangle Rect = new Rectangle();
    private Brush selectionBrush = new SolidBrush(Color.FromArgb(128, 72, 145, 220));
    
    // Start Rectangle
    //
    private void pictureBox1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
    {
        // Determine the initial rectangle coordinates...
        RectStartPoint = e.Location;
        Invalidate();
    }
    
    // Draw Rectangle
    //
    private void pictureBox1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
    {
        if (e.Button != MouseButtons.Left)
            return;
        Point tempEndPoint = e.Location;
        Rect.Location = new Point(
            Math.Min(RectStartPoint.X, tempEndPoint.X),
            Math.Min(RectStartPoint.Y, tempEndPoint.Y));
        Rect.Size = new Size(
            Math.Abs(RectStartPoint.X - tempEndPoint.X),
            Math.Abs(RectStartPoint.Y - tempEndPoint.Y));
        pictureBox1.Invalidate();
    }
    
    // Draw Area
    //
    private void pictureBox1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
    {
        // Draw the rectangle...
        if (pictureBox1.Image != null)
        {
            if (Rect != null && Rect.Width > 0 && Rect.Height > 0)
            {
                e.Graphics.FillRectangle(selectionBrush, Rect);
            }
        }
    }
    
    private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
            if (Rect.Contains(e.Location))
            {
                Debug.WriteLine("Right click");
            }
        }
    }