用于将png文件转换为视频文件的正确帧速率是多少?

时间:2016-06-23 02:37:15

标签: c# video png aforge avi

每1000 / 60fps毫秒我获取一个窗口的屏幕截图并将其保存为png文件到目录然后我使用VideoFileWriter从这些图像创建一个AVI文件。但我不知道我应该如何使用帧速率。我该如何定义它?它基于widthheight还是其他什么?我尝试复制virtualdub使用的默认帧速率,我发现它是1000 ..我尝试了这个速率,但视频输出速度非常慢。某些文档示例使用25。我真的不知道如何定义。

            const int width = 1920;
            const int height = 1080;
            const int frameRate = 60;

using (var writer = new VideoFileWriter())
            {
                writer.Open("output.avi", width, height, frameRate, VideoCodec.MPEG4);

                foreach (string file in Directory.EnumerateFiles(dest_path, "*.png"))
                {
                    using (var img = (Bitmap)Image.FromFile(file))
                    {
                        writer.WriteVideoFrame(img);
                    }
                }
            }

用于拍摄scouthhots的代码:

int i = 0;
        void doRecord()
        {  
            using (var img = GetScreenshot(handle))
            {
                string filename = Path.Combine(dest_path, string.Format("{0}.png", ++i));
                img.Save(filename, ImageFormat.Png);
            }
        }

        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;
            }
        }

我使用Timer来截取屏幕截图,设置如下:

const int fps = 60;
timer1.Interval = 1000 / fps;
timer1.Start();

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

2 个答案:

答案 0 :(得分:2)

您拍摄的图像的形状和/或尺寸与帧速率之间绝对没有相关性。

简答:

您需要计算每秒拍摄的截图数量,然后 对您的帧速率进行编号。

长答案:

我认为您错过了帧率的含义,我将解释: 人眼(与大多数动物一样)具有称为“Persistence of Vision”的属性,它基本上允许我们将对象的运动解释为连续的运动图像。这是所有视频所依据的概念。

如果你拍摄一张跑步者的照片,然后在你眼前快速传递它们,你会看到那个人在移动。但它不一定需要与实际人员相同的时间。我们在这里放一些数字作为背景。

你问你的朋友史蒂夫跑 1公里(大约半英里),然后你开始拍摄很多关于他跑步的照片。实际上,你每秒拍摄 60张照片。现在一般人以10公里/小时的速度跑,所以让我们使用那个跑步速度。史蒂夫1/10小时跑1公里,因为1小时内有3600秒与 360秒或6分钟相同。所以你拍摄了(60 * 360) 21600张照片

数据回顾:

  • 长度跑:1公里
  • 速度:10km / h
  • 时间:360秒
  • 每秒照片数:60
  • 总照片:21600

现在,如果你想重现这些照片,那么你需要花费相同的时间才能看到它们,因为史蒂夫跑了那个距离,你必须每秒显示你在中拍摄的60张照片第二。所以你最终会每秒显示60张照片。制作视频时,您将每张照片称为“框架”,因此您使用的是60帧/秒帧速率(或fps)。

如果您想要显示Steve运行的慢动作视频,您需要降低fps的数量,以低于30 fps的速度降低一半。这将让你有一个12分钟长的慢动作视频。

请注意,视频通常超过24 fps,fps越低,视频看起来越“滞后”

注意:我认真不建议使用该方法进行屏幕/窗口录制,因为这会导致计算机资源(CPU,RAM和硬盘)的大量浪费。您应该查找一些已经完成所有录制和修补的库。不幸的是,我没有任何建议。

答案 1 :(得分:1)

人眼可以看到20 fps的帧速率。良好的帧速率可能比这更大。但这取决于你制作视频的内容。如果视频仅用于保留,我建议使用30fps。