动画 GIF 的帧率似乎低于预期 [英] Animated GIF's framerate seems lower than expected
问题描述
我有一个 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).
我在 PictureBox
和 Label
上尝试过 gif,但结果速度相同.然后经过一些研究,我遇到了 this 问题和传奇@Hans Passant 的回答,但不幸的是,应用他建议的样板代码没有任何区别.
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?
推荐答案
你只能猜测,我怀疑有人会很幸运得到重现:
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屋!