GIF动画的帧率似乎低于预期 [英] Animated GIF's framerate seems lower than expected

查看:157
本文介绍了GIF动画的帧率似乎低于预期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个winforms应用程序,上面有一个gif,可以让用户了解停顿过程.

I have a winforms application, which has a gif on it for letting users know about stalling processes.

问题在于它的播放速度比在其他应用程序(chrome,Internet Explorer)上的播放速度慢得多.

The problem is it plays much slower than it seems on other applications (chrome, internet explorer).

我在PictureBoxLabel上尝试了gif,但是得到的速度是相同的.然后经过一些研究,我发现

I have tried the gif on PictureBox and Label but resulting speed is same. Then after a little research I've come accross this question and the answer of legendary @Hans Passant, but unfortunately applying the boilerplate code suggested by him didn't make any difference.

下面是简单的复制代码:

Below is the simple reproducing code:

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

以及设计器代码(如果需要):

And the designer code if needed:

partial class Form1
{
    private System.ComponentModel.IContainer components = null;

    protected override void Dispose ( bool disposing )
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    #region Windows Form Designer generated code

    private void InitializeComponent ()
    {
        System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
        this.pictureBox1 = new System.Windows.Forms.PictureBox();
        this.label1 = new System.Windows.Forms.Label();
        ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
        this.SuspendLayout();
        //
        // pictureBox1
        //
        this.pictureBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
        this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image")));
        this.pictureBox1.Location = new System.Drawing.Point(8, 9);
        this.pictureBox1.Name = "pictureBox1";
        this.pictureBox1.Size = new System.Drawing.Size(166, 119);
        this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
        this.pictureBox1.TabIndex = 0;
        this.pictureBox1.TabStop = false;
        //
        // label1
        //
        this.label1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
        this.label1.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
        this.label1.Image = ((System.Drawing.Image)(resources.GetObject("label1.Image")));
        this.label1.Location = new System.Drawing.Point(180, 9);
        this.label1.Name = "label1";
        this.label1.Size = new System.Drawing.Size(158, 119);
        this.label1.TabIndex = 1;
        //
        // Form1
        //
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(346, 134);
        this.Controls.Add(this.label1);
        this.Controls.Add(this.pictureBox1);
        this.Name = "Form1";
        this.Text = "Form1";
        ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
        this.ResumeLayout(false);

    }

    #endregion

    private System.Windows.Forms.PictureBox pictureBox1;
    private System.Windows.Forms.Label label1;
}

两个gif都以相同的速度播放,但低于实际的gif.应用此代码时,我还有其他要注意的地方吗?

Both gifs play at same speed, but lower than the actual gif. Is there any other points that I should be aware of while applying this code?

推荐答案

您只能猜测,我怀疑有人会很幸运地获得repro:

You can only get guesses, I doubt anybody will have much luck getting a repro:

  • timeBeginPeriod()从技术上讲可能会失败,尽管当您要求10毫秒时这很不正常,请确认它返回0.
  • 如果图像较大,则可能无法足够快地更新.否则您的UI线程会被其他任务占用过多. gif的像素格式与现代计算机上的视频适配器的像素格式匹配不佳.每次更新框架时都会完成转换.这是相当昂贵的,尤其是如果您还强制图像要重新缩放(即PictureBox.SizeMode!= Normal).使用任务管理器来验证您的UI线程未消耗100%的内核.
  • 您可以通过在提升权限的命令提示符下运行powercfg /energy来获得有关有效计时器期限的第二种意见.在您的应用程序运行时执行此操作.它将滚动一分钟,然后生成一个HTML文件,您可以使用浏览器查看该文件.在平台计时器分辨率:计时器请求堆栈"标题下报告,请求的期间"值应为10000.请注意,其他进程或驱动程序也可能已发出请求.
  • timeBeginPeriod() can technically fail, although that is very unusual when you ask for 10 msec, verify that it returns 0.
  • If the image is large then it might just not be able to update fast enough. Or your UI thread is occupied too much with other duties. The pixel format of a gif is a poor match with the pixel format of the video adapter on a modern machine. The conversion is done every time the frame is updated. It is fairly expensive, especially so if you also force the image to be rescaled (i.e. PictureBox.SizeMode != Normal). Use Task Manager to verify that your UI thread is not burning 100% core.
  • You can get a second opinion about the effective timer period by running powercfg /energy from an elevated command prompt. Do so while your app is running. It will trundle for a minute and then generate an HTML file that you can look at with your browser. Reported under the "Platform Timer Resolution:Timer Request Stack" heading, the Requested Period value should be 10000. Beware that other processes or drivers might also have made requests.

这篇关于GIF动画的帧率似乎低于预期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆