C#中的Gif动画文件具有比它们应有的更低的帧速率

时间:2014-08-19 11:35:20

标签: c# performance gif frame-rate

在我的软件完成运行之后,我得到了一个全屏加载页面,其中包括一个预加载器gif文件....这就像一个Windows 8用于商店和地铁。

然而问题是,无论gif文件的fps和速度是多少,C#窗体都会显示相同的低fps。

我真的不知道如何处理它,因为我试图在互联网上寻找解决方案,但无论我遇到什么都不清楚或无关。

我怀疑编译器忽略了我导入的gif文件中集成的fps。 但我不知道如何将fps设置为文件的内容,或者让IDE / Compiler在文件中忽略其规则。请指出< 3

这是我正在使用的文件属性的链接 http://preloaders.net/en/search/windows%208 从顶行到中间的那个...它有75帧,其余的就是它......

我目前正在使用图片框控件将gif包含在我的项目中(在winform项目中)

2 个答案:

答案 0 :(得分:9)

这是正常的事故,GIF以10毫秒为单位指定帧的显示时间。但是,默认情况下,Windows上的计时器对于低时间间隔不够准确。定时器由系统时钟中断更新,默认情况下每秒定时64次。为定时器提供不超过15.625毫秒的准确度。实际上,你的GIF将以2/3速度播放,给予或接受。

您可以通过启动其他程序来更改结果,例如Windows Media Player或Firefox或Chrome等浏览器。你会突然看到你的GIF以设计速度播放。

这些程序必须做同样的事情,改变时钟中断率以获得一致的播放速度。你需要对timeBeginPeriod进行pinvoke,传递10以将定时器精度提高到10毫秒。如果您的UI线程没有响应并且启动计时器太晚,您可能需要降低。当你不再需要播放时,一定要再次调用timeEndPeriod(),通常是在FormClosed事件处理程序中。

Boilerplate代码:

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
        timeBeginPeriod(timerAccuracy);
    }

    protected override void OnFormClosed(FormClosedEventArgs e) {
        timeEndPeriod(timerAccuracy);
        base.OnFormClosed(e);
    }

    // Pinvoke:
    private const int timerAccuracy = 10;
    [System.Runtime.InteropServices.DllImport("winmm.dll")]
    private static extern int timeBeginPeriod(int msec);
    [System.Runtime.InteropServices.DllImport("winmm.dll")]
    public static extern int timeEndPeriod(int msec);
}

答案 1 :(得分:0)

已接受的问题对我不起作用,或者我做对了。

但是我找到了一个解决方案,方法是使用计时器。查看此链接:https://social.msdn.microsoft.com/Forums/vstudio/en-US/c5ce514f-6fe7-4870-ae3f-c49fb946d294/too-slow-gif?forum=vbgeneral

是的,它是VB,但我们可以在C#中做类似的事情。他们还是关门了。 上述解决方案将gif加载到图像中,并在计时器滴答声中一张一张地加载图像。

就我而言,我提取了GIF图像中的所有帧,并将这些图像加载到表单构造函数中的图像数组中,应用类似的方法

    public partial class Splash : Form
{
    Image[] images = new Image[60];
    public Splash()
    {
        InitializeComponent();
        LoadImages();
    }

    private void LoadImages()
    {
        for (int i = 1; i <= 60; i++)
        {
            string path = $@"{Application.StartupPath}\loading\loading{i:0000}.png";
            Image image = Image.FromFile(path);
            images[i - 1] = image;
        }
    }

    int i = 0;
    private void timer1_Tick(object sender, EventArgs e)
    {
        i = i % 60;
        pictureBox1.Image = images[i];
        i += 1;
    }
}

我当时正在加载初始屏幕,最后我做了上面提到的事情。流畅,美观。只需调整计时器间隔以提高帧率即可。