采用具有OpenGL ES窗口的外部窗口的Screeshot

时间:2015-06-19 07:34:28

标签: android opengl-es hook genymotion

我试图捕获一个内部有一个opengl es窗口的Genymotion实例的屏幕截图。

问题是注入一个dll(钩子)捕获帧缓冲区没有工作作为例外(genymotion崩溃,无法挂钩帧缓冲,因为我不知道如何真正挂钩代理交换缓冲区的DLL)和公共解决方案,如glintercept或glproxy也没有工作(不知道如何使用它们)。使用easyhook注入一个像http://spazzarama.com/2011/03/14/c-screen-capture-and-overlays-for-direct3d-9-10-and-11-using-api-hooks/这样的dll,因为它的opengl而不是directx。

现在我的目标是在屏幕处于后台时截取屏幕截图。这适用于所有内部都没有opengl / directx的窗口。

通常屏幕一直是黑色的。我找到了几个使用SRCCOPY |的解决方案CAPTUREBLT但这会导致白色截图。

现在我尝试了不同的屏幕截图机制,但都是黑色或白色(在带有双显示器的genymotion x86上测试。

我还尝试捕获genymotion内容窗口的父窗口,这意味着代替了opengl hwnd,捕获了genymotion的主窗口。同样的结果。一切看起来都很棒但是opengl窗口仍然是黑色的。谁能告诉我如何挂钩捕获帧缓冲区的dll(gDebugger可以很好地显示图形)或为什么屏幕截图是黑色还是白色?

以下是我的截图代码。

   public Image TakeScreenshotFromHandle(IntPtr handle)
        {
            IntPtr hdcSrc = User32.GetWindowDC(handle);
            User32.RECT windowRect = new User32.RECT();
            User32.GetWindowRect(handle, out windowRect);
            int width = windowRect.Right - windowRect.Left;
            int height = windowRect.Bottom - windowRect.Top;
            IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
            IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
            IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
            GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.TernaryRasterOperations.SRCCOPY | GDI32.TernaryRasterOperations.CAPTUREBLT);
            GDI32.SelectObject(hdcDest, hOld);
            GDI32.DeleteDC(hdcDest);
            User32.ReleaseDC(handle, hdcSrc);
            Image img = Image.FromHbitmap(hBitmap);
            GDI32.DeleteObject(hBitmap);

            return img;

        }

   public Image TakeScreenshotFromHandle_2(IntPtr hwnd)
        {
            Clash_of_Clans_Genymotion_Bot.User32.RECT rc;
            User32.GetWindowRect(hwnd, out rc);
            Bitmap bmp = new Bitmap(rc.Right - rc.Left, rc.Bottom - rc.Top, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
            Graphics gfxBmp = Graphics.FromImage(bmp);
            IntPtr hdcBitmap = gfxBmp.GetHdc();
            User32.PrintWindow(hwnd, hdcBitmap, 0);
            gfxBmp.ReleaseHdc(hdcBitmap);
            gfxBmp.Dispose();
            bmp.Save("screenshothandle2.png");

            return bmp;
        }

现在我的想法是向窗口发送alt +打印按钮并抓取剪贴板的东西,因为剪贴板中的图形显示截图,但这是一个可怕的解决方案。最好的是捕获帧缓冲区。有没有人有一个简单的例子如何代理缓冲区(使用注入/挂钩)?

0 个答案:

没有答案