使用BitBlt捕获截图,如何?

时间:2013-08-09 05:12:23

标签: c# printing bitblt

我在搜索过程中不时遇到这个“BitBlt”,但我不知道如何使用它。

从人们的说法来看,它似乎是捕获Windows显示屏幕的最快方式。 但是,我不能自己说些什么,因为我没有工作。

我唯一能够设法使用的方法就是:

 gfxBmp.CopyFromScreen(0,0,0,0 rc.Size,CopyPixelOperation.CaptureBlt);

我猜哪个使用它? (rc.size =某个窗口的大小) 可悲的是,它没有做任何事情,我得到一张黑色照片。 但是,如果我使用SourceCopy,它可以工作,但这是正常的方法。

我目前正在尝试更换一些代码,使用BltBit,但它的效果不好:

    public MemoryStream CaptureWindow(IntPtr hwnd, EncoderParameters JpegParam)
    {
        NativeMethods.Rect rc;
        NativeMethods.GetWindowRect(hwnd, out rc);
        using (Bitmap bmp = new Bitmap(rc.Width, rc.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
        {

            using (Graphics gfxBmp = Graphics.FromImage(bmp))
            {
                IntPtr hdcBitmap = gfxBmp.GetHdc();
                try
                { 

                    NativeMethods.BitBlt(hdcBitmap, 0, 0, 0, 0, hwnd, 0, 0, 0xCC0020);

                }
                finally
                {
                    gfxBmp.ReleaseHdc(hdcBitmap);
                }
            }
            MemoryStream ms = new MemoryStream();
            bmp.Save(ms, GetEncoderInfo(ImageFormat.Jpeg), JpegParam);

            return ms;
        }
    }

1 个答案:

答案 0 :(得分:1)

你是对的, Graphics.CopyFromScreen已在内部使用BitBlt。以下是.NET 4.0 Framework中的代码:

// [...]
new UIPermission(UIPermissionWindow.AllWindows).Demand();
int width = blockRegionSize.Width;
int height = blockRegionSize.Height;
using (DeviceContext deviceContext = DeviceContext.FromHwnd(IntPtr.Zero))
{
    HandleRef hSrcDC = new HandleRef(null, deviceContext.Hdc);
    HandleRef hDC = new HandleRef(null, this.GetHdc());
    try
    {
        if (SafeNativeMethods.BitBlt(hDC, destinationX, destinationY, width, height, hSrcDC, sourceX, sourceY, (int)copyPixelOperation) == 0)
        {
            throw new Win32Exception();
        }
    }
    finally
    {
        this.ReleaseHdc();
    }
}

还有其他可能性来捕获屏幕截图。您也可以使用WinAPI函数PrintWindow

但对于图形卡加速的内容,两者都无效。硬件覆盖位于gpu-memory中,您无法访问它。这就是为什么你经常会为视频,游戏制作黑色图像......