【问题标题】:Building a screen capture构建屏幕截图
【发布时间】:2016-06-21 04:42:36
【问题描述】:

我正在尝试通过每隔x 毫秒对窗口进行一次屏幕截图来构建特定窗口的简单视频录制(然后将所有这些图像合并到一个 AVI 文件中),但我不知道如何定义值的x。我如何定义它?对此有什么共同价值?我读了一些关于 24fps 的文章。

我也不确定是否使用Timer,在Tick 事件中进行捕获是个好主意。我会有任何不准确的地方,我应该使用其他东西吗?例如,无论出于何种原因,屏幕截图的拍摄时间都比预期的要长。

我目前的实现是这样的:

  [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
   static extern bool GetWindowRect(IntPtr hWnd, out RECT r);

    public Bitmap GetScreenshot(IntPtr hwnd)
            {
                RECT rc;

                if (!GetWindowRect(hwnd, out rc))
                    throw new Win32Exception(Marshal.GetLastWin32Error());

                Bitmap bmp = new Bitmap(rc.right - rc.left, rc.bottom - rc.top, PixelFormat.Format32bppArgb);
                using (var gfxBmp = Graphics.FromImage(bmp))
                {
                    IntPtr hdcBitmap = gfxBmp.GetHdc();
                    bool succeeded = PrintWindow(hwnd, hdcBitmap, 0);
                    gfxBmp.ReleaseHdc(hdcBitmap);
                    if (!succeeded)
                    {
                        gfxBmp.FillRectangle(new SolidBrush(Color.Gray), new Rectangle(Point.Empty, bmp.Size));
                    }
                    IntPtr hRgn = CreateRectRgn(0, 0, 0, 0);
                    GetWindowRgn(hwnd, hRgn);
                    Region region = Region.FromHrgn(hRgn);
                    if (!region.IsEmpty(gfxBmp))
                    {
                        gfxBmp.ExcludeClip(region);
                        gfxBmp.Clear(Color.Transparent);
                    }
                    return bmp;
                }
            }

    int i = 0;
    const string dest_path = @"C:\Users\pc2\Desktop\images";
    void doRecord()
    {
        string filename = Path.Combine(dest_path, string.Format("{0}.png", ++i));
         // yeah, I'll add some error checking here soon as it gets working.
        GetScreenshot(handle).Save(filename, ImageFormat.Png);
    }

在计时器的滴答事件中我称之为:

private void timer1_Tick(object sender, EventArgs e)
        {
            doRecord();
        }

还有如何正确定义x 的值,我错过了什么吗?

【问题讨论】:

  • 我遇到了类似的挑战,发现解决方案是继续将图像发送到内存,然后让另一个线程每隔一段时间拉出图像。是的,它的 hacky 但我的时间线非常适合录制。希望这会有所帮助!

标签: c# windows screen-capture video-recording


【解决方案1】:

您必须为正在使用的计时器设置“间隔”参数。 “间隔”以毫秒为单位设置,因此如果您想要 ~24 FPS,请将“间隔”设置为 42(1000(每秒毫秒)/24(所需 FPS)=42)。

【讨论】:

  • 抱歉,如果不清楚,我的问题是拍摄截图的好间隔是多少。我知道如何设置时间的间隔属性。
  • 通常情况下,您应该瞄准的 FPS 是 30(但更接近显示器刷新率的值,通常是 60,会更好..) - 这可以消除屏幕闪烁,如果您是把图片合并成视频,应该很不错。
猜你喜欢
  • 2012-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-18
  • 1970-01-01
  • 2021-07-12
  • 2014-09-26
  • 1970-01-01
相关资源
最近更新 更多