【问题标题】:How to slow down animated gif如何减慢动画 gif
【发布时间】:2012-08-16 03:12:53
【问题描述】:

我有一个 WinForms 应用程序,它以最简单的方式显示动画 gif - 有一个直接加载 .gif 的 PictureBox。

WinForms 设计器生成的代码如下所示:

        // 
        // pictureBoxHomer
        // 
        this.pictureBoxHomer.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
        this.pictureBoxHomer.Dock = System.Windows.Forms.DockStyle.Fill;
        this.pictureBoxHomer.Image = ((System.Drawing.Image)(resources.GetObject("pictureBoxHomer.Image")));
        this.pictureBoxHomer.Location = new System.Drawing.Point(3, 3);
        this.pictureBoxHomer.Name = "pictureBoxHomer";
        this.pictureBoxHomer.Size = new System.Drawing.Size(905, 321);
        this.pictureBoxHomer.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
        this.pictureBoxHomer.TabIndex = 0;
        this.pictureBoxHomer.TabStop = false;

图片当然是这个:http://media.tumblr.com/tumblr_m1di1xvwTe1qz97bf.gif

问题:虽然这个动画 gif 在浏览器中显示得非常好,但在 WinForms 应用程序中运行速度太快了,这并不像需要的那样快乐。所以:

问题:有没有办法让 WinForms 应用程序中的 gif 动画变慢?

【问题讨论】:

  • 浏览器可能将 gif 限制为指定的 FPS。 Windows 运行它的速度可能与机器可以处理下一帧的速度一样快。
  • @Stieffers IIRC,GIF 格式允许在每一帧中指定帧时间。至少,一些编辑会这样做。 winforms 会忽略这一点似乎很奇怪,但也许确实如此?
  • 我不确定 Winforms 的复杂性,但我非常怀疑 Winforms 会为它加载的每个 GIF 图像创建一个新线程,这意味着它会尽可能避免渲染下一帧事件委托中的任何小插曲。

标签: c# winforms gif animated


【解决方案1】:

我相信答案与图像相关,而不是 C#。如果您在 GIMP 之类的工具中编辑该特定图像并查看图层,您会看到它由 10 个图层(帧)组成,但它们之间没有设置“延迟时间” - 它在图层中有 (0ms)属性。您可以编辑图层的属性并通过右键单击它并在菜单中选择该选项来更改它。当然,最后您必须导出新图像并将其保存为 GIF,在选项中选择“动画”。

我相信在这种情况下(当没有指定帧之间的延迟时间时)Web 浏览器和 C# PicutureBox 会强制使用它们自己不同的默认值。所以,如果你设置一个延迟,比如说 100 毫秒,就像在第 3 步中描述的here,你会让动画变慢。

【讨论】:

  • 谢谢你,你让我的下午充满活力——这很完美。
  • 如果您有很多帧,您可以通过在 GIMP 导出步骤中指定所有帧的延迟来避免很多手腕疼痛。该选项的标题为“对所有帧使用上面输入的延迟”。
  • 我的动画 gif 在所有帧(总共 90 帧)之间的延迟时间为 30 毫秒,在 IE 中更快,但在 winform 图片框中较慢。知道为什么它很慢。我希望它和 IE 中的一样
【解决方案2】:

为了将来参考,可以覆盖图片框中 GIF 的延迟时间。这是一个粗略的例子:

    public partial class Form1 : Form
{
    private FrameDimension dimension;
    private int frameCount;
    private int indexToPaint;
    private Timer timer = new Timer();

    public Form1()
    {
        InitializeComponent();

        dimension = new FrameDimension(this.pictureBox1.Image.FrameDimensionsList[0]);
        frameCount = this.pictureBox1.Image.GetFrameCount(dimension);
        this.pictureBox1.Paint += new PaintEventHandler(pictureBox1_Paint); 
        timer.Interval = 100;
        timer.Tick += new EventHandler(timer_Tick);
        timer.Start();
    }

    void timer_Tick(object sender, EventArgs e)
    {
        indexToPaint++;
        if(indexToPaint >= frameCount)
        {
            indexToPaint = 0;
        }
    }

    void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        this.pictureBox1.Image.SelectActiveFrame(dimension, indexToPaint);
        e.Graphics.DrawImage(this.pictureBox1.Image, Point.Empty);
    }
}

【讨论】:

    猜你喜欢
    • 2017-01-18
    • 2022-12-03
    • 1970-01-01
    • 1970-01-01
    • 2015-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    相关资源
    最近更新 更多