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,但是得到的速度是相同的.然后经过一些研究,我发现
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屋!