Let the user select a rectangular area in an image in C#

The program starts by defining a couple of variables that it uses while selecting the area. The bmOriginal variable holds a copy of the original image so we don't mess it up. The value IsSelecting is true while the user is selecting an area. Finally, x0, y0, x1, and y1 are the corners of the selected rectangle.

// The original image.
private Bitmap bmOriginal;

// True when we're selecting a rectangle.
private bool IsSelecting = false;
private int x0, y0, x1, y1;

// Save the original image.
private void Form1_Load(object sender, EventArgs e)
{
bmOriginal = new Bitmap(picOriginal.Image);
}

To let the user select an area, this example uses a PictureBox's MouseDown, MouseMove, and MouseUp events.

When the user presses the mouse down, the MouseDown event handler starts the process. It sets IsSelecting to true and saves the current mouse position.

// Start selecting the rectangle.
private void picOriginal_MouseDown(object sender, MouseEventArgs e)
{
IsSelecting = true;

// Save the start point.
x0 = e.X;
y0 = e.Y;
}

The MouseMove event handler saves the mouse's current location. It then copies the original Bitmap, draws a rectangle on it between the start and current points, and displays the result in the PictureBox on which the user is selecting.

// Continue selecting.
private void picOriginal_MouseMove(object sender, MouseEventArgs e)
{
// Do nothing it we're not selectign an area.
if (!IsSelecting) return;

// Save the new point.
x1 = e.X;
y1 = e.Y;

// Make a Bitmap to display the selection rectangle.
Bitmap bm = new Bitmap(bmOriginal);

// Draw the rectangle.
using (Graphics gr = Graphics.FromImage(bm))
{
gr.DrawRectangle(Pens.Red,
Math.Min(x0, x1), Math.Min(y0, y1),
Math.Abs(x0 - x1), Math.Abs(y0 - y1));
}

// Display the temporary bitmap.
picOriginal.Image = bm;
}

The MouseUp event handler finishes the process. It sets IsSelecting to false so future MouseMoves don't do anything, and it makes the selection PictureBox display its original image.

It then makes a new Bitmap big enough to hold the selected area and copies that area from the original image. Finally it displays the result in the picResult PictureBox. Your program might do something different such as copying the new Bitmap to the clipboard.

// Finish selecting the area.
private void picOriginal_MouseUp(object sender, MouseEventArgs e)
{
// Do nothing it we're not selecting an area.
if (!IsSelecting) return;
IsSelecting = false;

// Display the original image.
picOriginal.Image = bmOriginal;

// Copy the selected part of the image.
int wid = Math.Abs(x0 - x1);
int hgt = Math.Abs(y0 - y1);
if ((wid < 1) || (hgt < 1)) return;

Bitmap area = new Bitmap(wid, hgt);
using (Graphics gr = Graphics.FromImage(area))
{
Rectangle source_rectangle =
new Rectangle(Math.Min(x0, x1), Math.Min(y0, y1), wid, hgt);
Rectangle dest_rectangle =
new Rectangle(0, 0, wid, hgt);
gr.DrawImage(bmOriginal, dest_rectangle,
source_rectangle, GraphicsUnit.Pixel);
}

// Display the result.
picResult.Image = area;
}

   

 

What did you think of this article?




Trackbacks
  • No trackbacks exist for this post.
Comments

  • 2/11/2013 11:26 AM vic wrote:
    Buen tutorial; si lo acompañases con gr.Clear() tal vez sería más usable; así si se mueve el ratón mientras se selecciona, no 'mancha' toda la pantalla

    Gracias!
    Reply to this
    1. 2/12/2013 4:07 PM Rod Stephens wrote:
      Sorry but I don't understand. Perhaps this didn't translate very well.

      Do you mean to clear the output area while selecting an image? That's certainly possible.
      Reply to this
Leave a comment

Submitted comments are subject to moderation before being displayed.

 Name

 Email (will not be published)

 Website

Your comment is 0 characters limited to 3000 characters.