我有一个.NET控件,可以通过非托管代码输出视频。
我想要捕获控制客户区(视频帧)。
方法 Control.DrawToBitmap 不起作用,它输出控件背景 - 灰色。
然后我尝试使用GDI的 BitBlt :
[DllImport("gdi32.dll")]
private static extern bool BitBlt(
IntPtr hdcDest, // handle to destination DC
int nXDest, // x-coord of destination upper-left corner
int nYDest, // y-coord of destination upper-left corner
int nWidth, // width of destination rectangle
int nHeight, // height of destination rectangle
IntPtr hdcSrc, // handle to source DC
int nXSrc, // x-coordinate of source upper-left corner
int nYSrc, // y-coordinate of source upper-left corner
int dwRop // raster operation code
);
private const int SRCCOPY = 0xCC0020;
private void btnSave_Click(object sender, EventArgs e)
{
Graphics graphic = captureBox.CreateGraphics();
Bitmap memImage = new Bitmap(captureBox.Width, captureBox.Height, graphic);
Graphics memGraphic = Graphics.FromImage(memImage);
IntPtr dc1 = graphic.GetHdc();
IntPtr dc2 = memGraphic.GetHdc();
BitBlt(dc2, 0, 0, this.captureBox.ClientRectangle.Width,
this.captureBox.ClientRectangle.Height, dc1, 0, 0, SRCCOPY);
graphic.ReleaseHdc(dc1);
memGraphic.ReleaseHdc(dc2);
memImage.Save("capture.bmp", ImageFormat.Bmp);
}
它有效,但问题是它捕获了所有 - 甚至超过捕获控件的控件。
我想捕获控制客户端区域,即使它是重叠的。如何实现?
答案 0 :(得分:1)
这个应该工作但是已经有一段时间了,因为我已经用winforms编写代码来执行此操作...如果不能,我可以重新创建它。
而不是
Graphics graphic = captureBox.CreateGraphics();
IntPtr dc1 = graphic.GetHdc();
DO
[DllImport("gdi32.dll")]
private static extern IntPtr GetDC(IntPtr hWnd)
[DllImport("gdi32.dll")]
private static extern int ReleaseDc(IntPtr hWnd, IntPtr hDc)
// ...
IntPtr dc1 = GetDc(captureBox.Handle);
// ...
ReleaseDc(captureBox.Handle,dc1);
另请注意,如果这为您提供灰色背景,则可能意味着非托管代码未呈现到您的窗口中,而是在其上创建的另一个窗口。你可以看出spy ++是否属于这种情况。