问题
I am using the win32 PrintWindow function to capture a screen to a BitMap object.
If I only want to capture a region of the window, how can I crop the image in memory?
Here is the code I'm using to capture the entire window:
[System.Runtime.InteropServices.DllImport(strUSER32DLL, CharSet = CharSet.Auto, SetLastError = true)]
public static extern int PrintWindow(IntPtr hWnd, IntPtr hBltDC, uint iFlags);
public enum enPrintWindowFlags : uint
{
/// <summary>
///
/// </summary>
PW_ALL = 0x00000000,
/// <summary>
/// Only the client area of the window is copied. By default, the entire window is copied.
/// </summary>
PW_CLIENTONLY = 0x00000001
}
public System.Drawing.Bitmap CaptureWindow(IntPtr hWnd, enPrintWindowFlags eFlags)
{
System.Drawing.Rectangle rctForm = System.Drawing.Rectangle.Empty;
using(System.Drawing.Graphics grfx = System.Drawing.Graphics.FromHdc(GetWindowDC(hWnd)))
{
rctForm = System.Drawing.Rectangle.Round(grfx.VisibleClipBounds);
}
System.Drawing.Bitmap pImage = new System.Drawing.Bitmap(rctForm.Width, rctForm.Height);
System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(pImage);
IntPtr hDC = graphics.GetHdc();
//paint control onto graphics using provided options
try
{
PrintWindow(hWnd, hDC, (uint)eFlags);
}
finally
{
graphics.ReleaseHdc(hDC);
}
return pImage;
}
回答1:
You could simply grab the whole screen and then pass the image into a cropping function that selects a region of the total image. Take a look at the Bitmap.Clone() method. e.g.
public Bitmap CropBitmap(Bitmap bitmap, int cropX, int cropY, int cropWidth, int cropHeight)
{
Rectangle rect = new Rectangle(cropX, cropY, cropWidth, cropHeight);
Bitmap cropped = bitmap.Clone(rect, bitmap.PixelFormat);
return cropped;
}
Note, I pulled this down from this blog
回答2:
Here's the complete code to capture the screen and create a cropped image of 100 pixels square. The code is taken from a button Click event. Use what you need.
Bitmap screenShot = null;
Bitmap croppedImage;
Graphics screen;
if(saveFileDialog.ShowDialog() == DialogResult.OK)
{
this.Hide();
screenShot = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height,
PixelFormat.Format32bppArgb);
screen = Graphics.FromImage(screenShot);
screen.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
Screen.PrimaryScreen.Bounds.Y,
0,
0,
Screen.PrimaryScreen.Bounds.Size,
CopyPixelOperation.SourceCopy);
screenShot.Save(saveFileDialog.FileName, ImageFormat.Png);
this.Show();
}
//crop image
if(screenShot != null)
{
if(saveFileDialog.ShowDialog() == DialogResult.OK)
{
int x = 100;
int y = 100;
int xWidth = 100;
int yHeight = 100;
Rectangle rect = new Rectangle(x, y, xWidth, yHeight);
croppedImage = screenShot.Clone(rect, PixelFormat.Format32bppArgb);
if (croppedImage != null)
{
croppedImage.Save(saveFileDialog.FileName, ImageFormat.Png);
}
}
}
回答3:
Save yourself some trouble and pick up the source to Cropper.
来源:https://stackoverflow.com/questions/3241220/how-to-capture-part-of-a-screen