采取的所有可见的应用程序和形式的多个桌面的屏幕截图 [英] Take screenshot of multiple desktops of all visible applications and forms

查看:180
本文介绍了采取的所有可见的应用程序和形式的多个桌面的屏幕截图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用具有4个输出(显示器)与例如一个系统工作1280x1024像素的每个输出。我需要整个桌面上的所有打开的应用程序的截图。



我试过的 GetDesktopWindow()(MSDN),但它不T正常工作。有些形式不上捕获的图像显示。


解决方案

我试过GetDesktopWindow()函数,但它不能正常工作。




当然不是。



GetDesktopWindow 函数返回一个的处理的桌面窗口。它没有任何与捕获该窗口的图像。



此外,桌面窗口是不一样的东西全屏幕。它特指桌面窗口。请参见这篇文章的更多信息,什么可以去错了,当你虐待该函数返回的句柄。




我的工作与有4个输出(监视器)的系统具有1280×1024(EG)为每输出。我需要从整个桌面和所有打开的应用程序的截图。




这是比较简单的使用.NET Framework中的做 Graphics.CopyFromScreen 方法。你甚至都不需要做任何的P / Invoke!



在这种情况下,唯一的问题是确保您通过适当的尺寸。既然你有4个显示器,传球只有主屏尺寸将无法工作。您需要将整个虚拟屏幕,其中包含所有显示器的尺寸。通过查询 SystemInformation.VirtualScreen 属性,它返回虚拟屏幕的边界。正如文件指出,这是一个多显示器系统的整个桌面的边界



示例代码:

  //确定了虚拟屏幕,其中包括所有监视器的大小。 
INT screenLeft = SystemInformation.VirtualScreen.Left;
INT screenTop = SystemInformation.VirtualScreen.Top;
INT屏幕宽度= SystemInformation.VirtualScreen.Width;
INT screenHeight = SystemInformation.VirtualScreen.Height;

//创建适当大小的位图来接收的屏幕截图。使用(BMP位图=新位图(屏幕宽度,screenHeight))
{
//绘制的截图到我们的位图
。使用
(图形G = Graphics.FromImage(BMP))
{
g.CopyFromScreen(screenLeft,screenTop,0,0,bmp.Size);
}

//使用位图的东西在这里,喜欢它保存到一个文件:
bmp.Save(savePath,ImageFormat.Jpeg);
}






修改:




请检查在一个线程WPF应用程序,是不是你的主线程解决方案。我试了一下。这是行不通的!




嗯,我没有看到关于这个问题的WPF标签,或在身体的任何地方提及。



不管了,虽然。该代码我张贴的作品只是在一个WPF应用程序很好,只要你添加适当的引用和使用声明。您需要 System.Windows.Forms的 System.Drawing中。有可能是这样做的更多的WPF式的方式,不要求对这些的WinForms组件的依赖,但我不知道它是什么。



据甚至可以在另一个线程。这里没有什么是需要的UI线程。



是的,我测试了它。这里是我完整的测试代码:

 使用System.Windows;使用System.Windows.Forms的
; //还要求本次大会
使用System.Drawing中的参考; //还要求本次大会
使用System.Drawing.Imaging的引用;
使用的System.Threading;

公共部分类主窗口:窗口
{
公共主窗口()
{
的InitializeComponent();
}

私人无效的button1_Click(对象发件人,RoutedEventArgs E)
{
//创建一个用于演示的一个新的线程。
线程线程=新主题(()=>
{
//确定了虚拟屏幕,其中包括所有的监视器
INT screenLeft = SystemInformation的大小。 VirtualScreen.Left;
INT screenTop = SystemInformation.VirtualScreen.Top;
INT屏幕宽度= SystemInformation.VirtualScreen.Width;
INT screenHeight = SystemInformation.VirtualScreen.Height;

//创建一个适当大小的使用位图(BMP位图=新位图(屏幕宽度,screenHeight))
{
//绘制的截图到我们的位图来获得的截图。
。使用
(图形G = Graphics.FromImage(BMP))
{
g.CopyFromScreen(screenLeft,screenTop,0,0,bmp.Size);
}

//做一些与位图在这里,喜欢它保存到一个文件:
bmp.Save(G:\\TestImage.jpg,ImageFormat.Jpeg);
}
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
}


I'm working with a system that has 4 outputs (monitors) with e.g. 1280x1024 pixels for each output. I need a screenshot of the whole desktop and all open applications on it.

I tried GetDesktopWindow() (MSDN) but it doesn't work properly. Some forms don't shown on the captured picture.

解决方案

i tried GetDesktopWindow() function but it doesn't work properly.

Of course not.

The GetDesktopWindow function returns a handle to the desktop window. It doesn't have anything to do with capturing an image of that window.

Besides, the desktop window is not the same thing as "the entire screen". It refers specifically to the desktop window. See this article for more information and what can go wrong when you abuse the handle returned by this function.

i'm working with a system that have 4 outputs (monitors) with 1280x1024(e.g) for each output. i need a screenshot from whole desktop and all open applications on it.

This is relatively simple to do in the .NET Framework using the Graphics.CopyFromScreen method. You don't even need to do any P/Invoke!

The only trick in this case is making sure that you pass the appropriate dimensions. Since you have 4 monitors, passing only the dimensions of the primary screen won't work. You need to pass the dimensions of the entire virtual screen, which contains all of your monitors. Retrieve this by querying the SystemInformation.VirtualScreen property, which returns the bounds of the virtual screen. As the documentation indicates, this is the bounds of the entire desktop on a multiple monitor system.

Sample code:

// Determine the size of the "virtual screen", which includes all monitors.
int screenLeft   = SystemInformation.VirtualScreen.Left;
int screenTop    = SystemInformation.VirtualScreen.Top;
int screenWidth  = SystemInformation.VirtualScreen.Width;
int screenHeight = SystemInformation.VirtualScreen.Height;

// Create a bitmap of the appropriate size to receive the screenshot.
using (Bitmap bmp = new Bitmap(screenWidth, screenHeight))
{
    // Draw the screenshot into our bitmap.
    using (Graphics g = Graphics.FromImage(bmp))
    {
        g.CopyFromScreen(screenLeft, screenTop, 0, 0, bmp.Size);
    }

    // Do something with the Bitmap here, like save it to a file:
    bmp.Save(savePath, ImageFormat.Jpeg);
}


Edit:

please check your solution with a wpf application in a thread that is not your main thread. i tried it. it doesn't work!

Hmm, I didn't see a WPF tag on the question or mentioned anywhere in the body.

No matter, though. The code I posted works just fine in a WPF application, as long as you add the appropriate references and using declarations. You will need System.Windows.Forms and System.Drawing. There might be a more WPF-esque way of doing this that doesn't require a dependency on these WinForms assemblies, but I wouldn't know what it is.

It even works on another thread. There is nothing here that would require the UI thread.

Yes, I tested it. Here is my full test code:

using System.Windows;
using System.Windows.Forms;   // also requires a reference to this assembly
using System.Drawing;         // also requires a reference to this assembly
using System.Drawing.Imaging;
using System.Threading;

public partial class MainWindow : Window
{
   public MainWindow()
   {
      InitializeComponent();
   }

   private void button1_Click(object sender, RoutedEventArgs e)
   {
      // Create a new thread for demonstration purposes.
      Thread thread = new Thread(() =>
      {
         // Determine the size of the "virtual screen", which includes all monitors.
         int screenLeft   = SystemInformation.VirtualScreen.Left;
    int screenTop    = SystemInformation.VirtualScreen.Top;
    int screenWidth  = SystemInformation.VirtualScreen.Width;
    int screenHeight = SystemInformation.VirtualScreen.Height;

         // Create a bitmap of the appropriate size to receive the screenshot.
         using (Bitmap bmp = new Bitmap(screenWidth, screenHeight))
         {
            // Draw the screenshot into our bitmap.
            using (Graphics g = Graphics.FromImage(bmp))
            {
               g.CopyFromScreen(screenLeft, screenTop, 0, 0, bmp.Size);
            }

            // Do something with the Bitmap here, like save it to a file:
            bmp.Save("G:\\TestImage.jpg", ImageFormat.Jpeg);
         }
      });
      thread.SetApartmentState(ApartmentState.STA);
      thread.Start();
   }
}

这篇关于采取的所有可见的应用程序和形式的多个桌面的屏幕截图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆