Language agnostic 捕捉屏幕的最快方式是什么?任何语言

Language agnostic 捕捉屏幕的最快方式是什么?任何语言,language-agnostic,screen,screenshot,capture,Language Agnostic,Screen,Screenshot,Capture,我需要非常非常快地拍摄Windows应用程序的打印屏幕,以便将其制作成视频。。。我一直在使用C#语言,但我对任何语言都持开放态度,在这种语言中,这个过程可能会更快 我使用了很多技巧: .net函数:位图.CopyFromScreen() GDI Direct3d/DirectX 我最快的速度是使用GDI,但我每秒得到的照片还不到10张。我需要更多,至少20或30 这么简单的手术要求这么高,我觉得很奇怪。看起来使用更快的cpu并不能改变这种情况 我能做什么?是否可以使用gdi或其他工具直接捕获

我需要非常非常快地拍摄Windows应用程序的打印屏幕,以便将其制作成视频。。。我一直在使用C#语言,但我对任何语言都持开放态度,在这种语言中,这个过程可能会更快

我使用了很多技巧:

  • .net函数:位图.CopyFromScreen()
  • GDI
  • Direct3d/DirectX
我最快的速度是使用GDI,但我每秒得到的照片还不到10张。我需要更多,至少20或30

这么简单的手术要求这么高,我觉得很奇怪。看起来使用更快的cpu并不能改变这种情况

我能做什么?是否可以使用gdi或其他工具直接捕获应用程序的绘图?或者甚至可以使用更低级别的函数来捕获抛出到图形卡的信息

对此问题的任何解释都将不胜感激。
非常感谢

许多程序使用驱动程序,并允许您的应用程序连接到较低级别的显示例程。我不确定这是怎么做到的,但这是可能的。 下面是编写Windows驱动程序的起点

以下是我刚刚通过谷歌找到的一些东西:

您可能希望使用类似的内容。这取决于你为什么要制作视频

我使用Jeff的重写版本,他使用GDI的BitBlt来捕获屏幕截图。对我来说似乎足够快,但我还没有对它进行基准测试,我们只是在抛出未处理的异常时使用它进行一次一次的拍摄

#region Win32 API screenshot calls

// Win32 API calls necessary to support screen capture
[DllImport("gdi32", EntryPoint = "BitBlt", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
private static extern int BitBlt(int hDestDC, int x, int y, int nWidth, int nHeight, int hSrcDC, int xSrc,
                                 int ySrc, int dwRop);

[DllImport("user32", EntryPoint = "GetDC", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
private static extern int GetDC(int hwnd);

[DllImport("user32", EntryPoint = "ReleaseDC", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
private static extern int ReleaseDC(int hwnd, int hdc);

#endregion

private static ImageFormat screenshotImageFormat = ImageFormat.Png;

/// <summary>
/// Takes a screenshot of the desktop and saves to filename and format specified
/// </summary>
/// <param name="fileName"></param>
private static void TakeScreenshotPrivate(string fileName)
{
    Rectangle r = Screen.PrimaryScreen.Bounds;

    using (Bitmap bitmap = new Bitmap(r.Right, r.Bottom))
    {
        const int SRCCOPY = 13369376;

        using (Graphics g = Graphics.FromImage(bitmap))
        {
            // Get a device context to the windows desktop and our destination  bitmaps
            int hdcSrc = GetDC(0);
            IntPtr hdcDest = g.GetHdc();

            // Copy what is on the desktop to the bitmap
            BitBlt(hdcDest.ToInt32(), 0, 0, r.Right, r.Bottom, hdcSrc, 0, 0, SRCCOPY);

            // Release device contexts
            g.ReleaseHdc(hdcDest);
            ReleaseDC(0, hdcSrc);

            string formatExtension = screenshotImageFormat.ToString().ToLower();
            string expectedExtension = string.Format(".{0}", formatExtension);

            if (Path.GetExtension(fileName) != expectedExtension)
            {
                fileName += expectedExtension;
            }

            switch (formatExtension)
            {
                case "jpeg":
                    BitmapToJPEG(bitmap, fileName, 80);
                    break;
                default:
                    bitmap.Save(fileName, screenshotImageFormat);
                    break;
            }

            // Save the complete path/filename of the screenshot for possible later use
            ScreenshotFullPath = fileName;
        }
    }
}

/// <summary>
/// Save bitmap object to JPEG of specified quality level
/// </summary>
/// <param name="bitmap"></param>
/// <param name="fileName"></param>
/// <param name="compression"></param>
private static void BitmapToJPEG(Image bitmap, string fileName, long compression)
{
    EncoderParameters encoderParameters = new EncoderParameters(1);
    ImageCodecInfo codecInfo = GetEncoderInfo("image/jpeg");

    encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, compression);
    bitmap.Save(fileName, codecInfo, encoderParameters);
}
#区域Win32 API屏幕截图调用
//支持屏幕捕获所需的Win32 API调用
[DllImport(“gdi32”,EntryPoint=“BitBlt”,CharSet=CharSet.Ansi,SetLastError=true,ExactSpelling=true)]
私有静态外部int-BitBlt(int-hDestDC、int-x、int-y、int-nWidth、int-nHeight、int-hSrcDC、int-xSrc、,
int ySrc、int dwRop);
[DllImport(“user32”,EntryPoint=“GetDC”,CharSet=CharSet.Ansi,SetLastError=true,ExactSpelling=true)]
私有静态外部int GetDC(int hwnd);
[DllImport(“user32”,EntryPoint=“ReleaseDC”,CharSet=CharSet.Ansi,SetLastError=true,ExactSpelling=true)]
专用静态外部内部释放DC(内部hwnd、内部hdc);
#端区
私有静态ImageFormat screenshotImageFormat=ImageFormat.Png;
/// 
///获取桌面的屏幕截图并保存为指定的文件名和格式
/// 
/// 
私有静态void TakeScreenshotPrivate(字符串文件名)
{
矩形r=Screen.PrimaryScreen.Bounds;
使用(位图位图=新位图(右下)
{
const int SRCCOPY=13369376;
使用(Graphics g=Graphics.FromImage(位图))
{
//获取windows桌面和目标位图的设备上下文
int hdcSrc=GetDC(0);
IntPtr hdcDest=g.GetHdc();
//将桌面上的内容复制到位图
BitBlt(hdcDest.ToInt32(),0,0,右,右,下,hdcSrc,0,0,SRCCOPY);
//释放设备上下文
g、 释放HDC(hdcDest);
ReleaseDC(0,hdcSrc);
string formatExtension=screenshotImageFormat.ToString().ToLower();
string expectedExtension=string.Format(“.{0}”,formatExtension);
if(Path.GetExtension(fileName)!=expectedExtension)
{
fileName+=预期扩展;
}
交换机(格式化扩展)
{
案例“jpeg”:
BitmapToJPEG(位图,文件名,80);
打破
违约:
保存(文件名、屏幕快照图像格式);
打破
}
//保存屏幕截图的完整路径/文件名,以备将来使用
ScreenshotFullPath=文件名;
}
}
}
/// 
///将位图对象保存为指定质量级别的JPEG
/// 
/// 
/// 
/// 
私有静态void BitmapToJPEG(图像位图、字符串文件名、长压缩)
{
EncoderParameters EncoderParameters=新的EncoderParameters(1);
ImageCodecInfo codecInfo=GetEncoderInfo(“图像/jpeg”);
encoderParameters.Param[0]=新的EncoderParameter(Encoder.Quality,compression);
保存(文件名、编码信息、编码参数);
}

“fotogram”是一个真实的词吗?有很多应用程序都能很好地做到这一点。你确定要重新发明轮子吗?让我看看。。。这是一个“有用的应用”网站,还是一个编程问题网站?Chris,我做的gdi解决方案与你发布的非常相似,但是因为它有一些不同,我决定尝试一下。但是,它不识别函数“GetDC”、“BiBlt”和“ReleaseDC”。这些函数是你写的吗?您能提供给我吗?这些函数是DllImport属性引用的函数。我相信这些应该自动引用gdi32.dll和user32.dll。谷歌链接已经失效。为这样的场合写一篇摘录会有所帮助。