1

I have written a small application which will be used in my work environment for cropping images. The windows form (.NET 3.5) that contains the image has a transparent rectangle which I use for dragging over a section of an image and hitting a button to get me whatever was behind the rectangle.

Currently I am using the code below, this is causing me issues because the area that it is capturing is off by quite a few pixels, and I think it's something to do with my CopyFromScreen function.

    //Pass in a rectangle
    private void SnapshotImage(Rectangle rect)
    {
        Point ptPosition = new Point(rect.X, rect.Y);
        Point ptRelativePosition;

        //Get me the screen coordinates, so that I get the correct area
        ptRelativePosition = PointToScreen(ptPosition);

        //Create a new bitmap
        Bitmap bmp = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb);

        //Sort out getting the image
        Graphics g = Graphics.FromImage(bmp);

        //Copy the image from screen
        g.CopyFromScreen(this.Location.X + ptPosition.X, this.Location.Y + ptPosition.Y,   0,  0, bmp.Size, CopyPixelOperation.SourceCopy);
        //Change the image to be the selected image area
        imageControl1.Image.ChangeImage(bmp);  
    }

If anyone can spot why when the image is redrawn its quite a bit out, I'd be eternally grateful at this point. Also, the ChangeImage function is fine - it works if I use a form as a select area but using a rectangle has jazzed things up a bit.

Ry-
  • 218,210
  • 55
  • 464
  • 476
Adam H
  • 1,159
  • 3
  • 15
  • 27

2 Answers2

1

You've retrieved the relative position to the screen as ptRelativePosition, but you never actually use that - you add the rectangle's location to your form's location, which doesn't account for the form's border.

Here's that fixed, with a few optimizations:

// Pass in a rectangle
private void SnapshotImage(Rectangle rect)
{
    // Get me the screen coordinates, so that I get the correct area
    Point relativePosition = this.PointToScreen(rect.Location);

    // Create a new bitmap
    Bitmap bmp = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb);

    // Copy the image from screen
    using(Graphics g = Graphics.FromImage(bmp)) {
        g.CopyFromScreen(relativePosition, Point.Empty, bmp.Size);
    }

    // Change the image to be the selected image area
    imageControl1.Image.ChangeImage(bmp);  
}
Ry-
  • 218,210
  • 55
  • 464
  • 476
  • Hm, its still grabbing the wrong area, Y coordinates + 50 for some reason. – Adam H Feb 23 '12 at 07:58
  • Oh and the Point in your code is named 'relativePosition' but you reference it as ptRelativePosition - just so you know. – Adam H Feb 23 '12 at 08:03
  • @AdLib: Can you upload a project or something? (Sorry for the late reply, I didn't get a comment notification for some reason.) – Ry- Feb 23 '12 at 14:35
0

Interestingly, this was because of the space between the main form and the control that the image was on and the toolbar at the top of the form separating the control and the top of the main form. To get around this I simply modified one line in capture screen to account for those pixels, as shown below:

g.CopyFromScreen(relativePosition.X + 2, relativePosition.Y+48,  Point.Empty.X, Point.Empty.Y, bmp.Size);

Cheers

Adam H
  • 1,159
  • 3
  • 15
  • 27