I wrote a function that will take a control and a file destination and will save the area of the form the control covers.
My issue is that when I moved my from from my external monitors to my laptop's main screen, the capture area was shifted by an inconsistent amount. I finally figured out the scaling (DPI) was to blame. When I changed it down to 100% (96 DPI) it worked on the laptop screen. All other screens were already set to 100%. Back to 125% and it was only an issue on the laptop's screen. How do I allow 125%?
When on the laptop screen, the closer to the top left of screen the form is, the more accurate the location of the image is. The size of the image generated is the same on any screen, just the location changes when on the laptop screen. Also, the form resizes as I transition from the external monitor to the laptop display. It is after this resize that I get this issue.
private void capture(Control ctrl, string fileName)
{
Rectangle bounds = ctrl.Bounds;
Point pt = ctrl.PointToScreen(bounds.Location);
Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height);
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(new Point(pt.X - ctrl.Location.X, pt.Y - ctrl.Location.Y), Point.Empty, bounds.Size);
}
string filetype = fileName.Substring(fileName.LastIndexOf('.')).ToLower();
switch (filetype)
{
case ".png":
bitmap.Save(fileName, ImageFormat.Png);
break;
case ".jpeg":
bitmap.Save(fileName, ImageFormat.Jpeg);
break;
case ".bmp":
bitmap.Save(fileName, ImageFormat.Bmp);
break;
default:
break;
}
}
I couldn't find a way to fix it. I changed methods and used DrawToBitmap on the form then made a image from the control location. There was a fixed offset that i had to account for. I think it had to do with the top bar being included in the bitmap of the form and not included in the control's location in the form.
One thing to consider is DrawToBitmap draws in reverse stack order. If you have overlaying objects, you will likely need to reverse the order for the DrawToBitmap.
private void capture(Control ctrl, string fileName)
{
Bitmap bitmapForm = new Bitmap(this.Width, this.Height);
this.DrawToBitmap(bitmapForm, new Rectangle(0, 0, this.Width, this.Height));
Rectangle myControlRect = new Rectangle(ctrl.Location,ctrl.Size);
//Correct for boarder around form
myControlRect.Offset(8,31);
Bitmap bitmap = bitmapForm.Clone(myControlRect, PixelFormat.DontCare);
string filetype = fileName.Substring(fileName.LastIndexOf('.')).ToLower();
switch (filetype)
{
case ".png":
bitmap.Save(fileName, ImageFormat.Png);
break;
case ".jpeg":
bitmap.Save(fileName, ImageFormat.Jpeg);
break;
case ".bmp":
bitmap.Save(fileName, ImageFormat.Bmp);
break;
default:
break;
}
}