Copy an irregular area from one picture to another in C#

This example has two main tasks: letting the user select an irregular area and copying that area onto another picture.

The following code shows how the program lets the user select an irregular area.
// For selecting an area.
private List Points = null;
private bool Drawing = false;

// Start selecting an area.
private void picSource_MouseDown(object sender, MouseEventArgs e)
{
Points = new List();
Drawing = true;
}

// Continue selecting the area.
private void picSource_MouseMove(object sender, MouseEventArgs e)
{
if (!Drawing) return;
Points.Add(new Point(e.X, e.Y));
picSource.Invalidate();
}

// Stop selecting the area.
private void picSource_MouseUp(object sender, MouseEventArgs e)
{
Drawing = false;
btnCopy.Enabled = true;
}

// Draw the current selection if there is one.
private void picSource_Paint(object sender, PaintEventArgs e)
{
if ((Points != null) && (Points.Count > 1))
{
using (Pen dashed_pen = new Pen(Color.Black))
{
dashed_pen.DashPattern = new float[] { 5, 5 };
e.Graphics.DrawLines(Pens.White, Points.ToArray());
e.Graphics.DrawLines(dashed_pen, Points.ToArray());
}
}
}

When the user presses the mouse down on the picSource PictureBox, the code creates a new Points list and sets Drawing to true.

When the mouse moves over the PictureBox, the code adds a new point to the Points list and invalidates the PictureBox.

If the Points list contains at least 2 points, the Paint event handler draws lines connecting the points. First it draws the lines in white and then it draws dashed black lines over them. The result is a black and white dashed line.

When the user releases the mouse, the program sets Drawing to false to stop selecting an area and it enables the Copy button. When the user presses this button, the following code copies the selected area to the destination picture.

// Copy the selected area to the destination picture.
private void btnCopy_Click(object sender, EventArgs e)
{
// Make a new bitmap to hold the selected area.
Bitmap bm = new Bitmap(picSource.Image);
using (Graphics gr = Graphics.FromImage(bm))
{
// Clear the image with the transparent color.
gr.Clear(Color.Transparent);

// Make a brush out of the original image.
using (Brush br = new TextureBrush(picSource.Image))
{
// Fill the selected area with the brush.
gr.FillPolygon(br, Points.ToArray());

// Find the bounds of the selected area.
Rectangle source_rect = GetPointListBounds(Points);

// Copy the area to the middle of the destination picture.
Bitmap dest_bm = new Bitmap(DestImage);
using (Graphics dest_gr = Graphics.FromImage(dest_bm))
{
int x = (int)((dest_bm.Width - source_rect.Width) / 2);
int y = (int)((dest_bm.Height - source_rect.Height) / 2);
Rectangle dest_rect = new Rectangle(x, y,
source_rect.Width, source_rect.Height);
dest_gr.DrawImage(bm, dest_rect, source_rect, GraphicsUnit.Pixel);
}

// Display the result.
picDestination.Image = dest_bm;
}
}
}

The program makes a new bitmap that is the same size as the original picture. It clears the bitmap with the transparent color so all of its pixels are transparent.

Next the program creates a TextBrush. A TextBrush fills shapes with an image. This brush uses the original image. The code then fills the selected area with this brush. The result is that the new bitmap is transparent except for the selected area, which is filled with whatever is in that part of the original image.

The program uses the GetPointListBounds method to get a rectangle surrounding the selected area. (This method is straightforward--see the code for details.)

Finally the program draws the selected area's image to the center of the destination picture. You may want to modify this part to copy the image to some other position, let the user drag it around, etc. (I may add the ability to drag the image around later.)

   

 

What did you think of this article?




Trackbacks
  • No trackbacks exist for this post.
Comments
  • No comments exist for this post.
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.