【问题标题】:Using BitBlt to capture screenshot, how?使用BitBlt截屏,如何?
【发布时间】:2013-08-11 00:18:40
【问题描述】:

我在搜索中不时遇到这个“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;
        }
    }

【问题讨论】:

    标签: c# printing bitblt


    【解决方案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 内存中,您无法访问它。这就是为什么您经常在视频、游戏等中获得黑色图像...

    【讨论】:

    • 有吗?它甚至与 SourceCopy 一起使用吗?对于代码,我不知道如何在我的代码中实现它(我帖子中的其他代码段)。我目前正在使用 PrintWindow,不过,我遇到了一些问题,因为它会强制窗口一直刷新。有些应用程序不喜欢这样。
    • 该代码只是 CopyFromScreen 代码的摘录。使用 ILSpy(ilspy.net) 亲自查看。
    • 啊,那我明白你为什么这么写了。嗯,仍然需要让它以某种方式工作,因为我只得到一个黑屏,不管我用 BlBit 捕获什么(可以是桌面或其他)。
    猜你喜欢
    • 2018-05-27
    • 2012-04-20
    • 2011-10-26
    • 2017-09-21
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多