【问题标题】:Get a screenshot of desktop in full screen 3D-application在全屏 3D 应用程序中获取桌面截图
【发布时间】:2014-08-26 07:18:44
【问题描述】:

在使用全屏 3D 应用程序(例如游戏)时,是否可以将桌面渲染为屏幕截图?还是在游戏运行时windows会关闭渲染引擎?

我正在寻找在我的游戏中将桌面渲染为纹理的方法。类似 RDP 的协议能否成为解决方案?

编辑:澄清一下,是否有任何深层 api 机制可以强制渲染到另一个缓冲区,例如在制作屏幕截图时。不管是 Windows 7 还是 Windows 8/9。

【问题讨论】:

  • 我们在谈论游戏引擎中的“Unity”?如果是这样,正确的标签是 [unity3d]。
  • @Bart 谢谢,是的。与游戏引擎的关系不大,但我认为如果它重要的话,我会标记它。
  • 所以你问的是当游戏全屏运行时你是否仍然可以渲染桌面视图(在纹理中)?我的第一个猜测是“不可能”,但我没有足够的信息来支持它。附:如果 Unity 并不真正相关,请删除标签。但是,如果您正在寻找适用于 Unity 的解决方案,只需将其留在原处即可。
  • @Bart 是的,我知道正常的屏幕截图程序不起作用。但也许winapi中有一种方法可以强制重绘到另一个不可见的缓冲区(而不是屏幕)。 Unity 可能与渲染方式有关。例如,在窗口模式下,可以通过隐藏游戏窗口、强制重绘到另一个缓冲区然后继续它来实现。
  • 尝试在应用进入全屏模式之前截取桌面截图

标签: c# windows winapi unity3d rdp


【解决方案1】:

您可以通过调用桌面窗口的 hWnd 上的 PrintWindow Win32 API 函数来获取屏幕截图。我在 Windows 7 和 Windows 8.1 上试过这个,即使在另一个应用程序(VLC Player)全屏运行时它也能工作,所以它也有可能与游戏一起工作。这只会让您获得没有任务栏的桌面图像,但不会显示其他可见的正在运行的应用程序。如果您也需要这些,那么您也需要获取它们的 HWND(例如,通过枚举所有正在运行的进程并获取它们的窗口句柄),然后使用相同的方法。

using System;
using System.Drawing; // add reference to the System.Drawing.dll
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;

namespace DesktopScreenshot
{
  class Program
  {
    static void Main(string[] args)
    {
        // get the desktop window handle without the task bar
        // if you only use GetDesktopWindow() as the handle then you get and empty image
        IntPtr desktopHwnd = FindWindowEx(GetDesktopWindow(), IntPtr.Zero, "Progman", "Program Manager");

        // get the desktop dimensions
        // if you don't get the correct values then set it manually
        var rect = new Rectangle();
        GetWindowRect(desktopHwnd, ref rect);

        // saving the screenshot to a bitmap
        var bmp = new Bitmap(rect.Width, rect.Height);
        Graphics memoryGraphics = Graphics.FromImage(bmp);
        IntPtr dc = memoryGraphics.GetHdc();
        PrintWindow(desktopHwnd, dc, 0);
        memoryGraphics.ReleaseHdc(dc);

        // and now you can use it as you like
        // let's just save it to the desktop folder as a png file
        string desktopDir = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
        string screenshotPath = Path.Combine(desktopDir, "desktop.png");
        bmp.Save(screenshotPath, ImageFormat.Png);
    }

    [DllImport("User32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool PrintWindow(IntPtr hwnd, IntPtr hdc, uint nFlags);

    [DllImport("user32.dll")]
    static extern bool GetWindowRect(IntPtr handle, ref Rectangle rect);

    [DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
    static extern IntPtr GetDesktopWindow();

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string lclassName, string windowTitle); 
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-28
    • 2012-02-19
    • 2013-03-28
    • 2019-02-12
    • 1970-01-01
    相关资源
    最近更新 更多