如何在 GIF 结束后更改图片框
本文关键字:GIF 结束 | 更新日期: 2023-09-27 18:35:34
我有一个PictueBox,我有一些骰子,我想播放一个"掷骰子"的动画,我用骰子做了一个.gif,但是在骰子停止滚动后,我想要我得到的实际骰子编号,我有一个随机的功能来处理它。
我的问题是,我按下"掷骰子"按钮,它会播放动画,动画结束后,我应该在图片框中设置实际出现的骰子。 但它立即点击实际来的骰子数字,跳过动画;
这是它的工作原理:
dice1.Image = Resources.DiceAnimation; //Here the gif is called to be played
int x = rollDice(); //Here I roll the dice
switch (x){
case 1: dice.Image = resources.diceFace1; //Image set depending on x
break
case 2: //etc...
}
可能需要
做两件事。
首先,您可能需要确保您的PictureBox
收到 gif 图像并且它知道它。为此,请检查此答案和此答案。这些帖子有代码可以逐帧显示GifImage
:
public class GifImage
{
private Image gifImage;
private FrameDimension dimension;
private int frameCount;
private int currentFrame = -1;
private bool reverse;
private int step = 1;
public GifImage(string path)
{
gifImage = Image.FromFile(path);
//initialize
dimension = new FrameDimension(gifImage.FrameDimensionsList[0]);
//gets the GUID
//total frames in the animation
frameCount = gifImage.GetFrameCount(dimension);
}
public bool ReverseAtEnd {
//whether the gif should play backwards when it reaches the end
get { return reverse; }
set { reverse = value; }
}
public Image GetNextFrame()
{
currentFrame += step;
//if the animation reaches a boundary...
if (currentFrame >= frameCount || currentFrame < 1) {
if (reverse) {
step *= -1;
//...reverse the count
//apply it
currentFrame += step;
}
else {
currentFrame = 0;
//...or start over
}
}
return GetFrame(currentFrame);
}
public Image GetFrame(int index)
{
gifImage.SelectActiveFrame(dimension, index);
//find the frame
return (Image)gifImage.Clone();
//return a copy of it
}
}
像这样使用它(请注意,您需要一个Timer
对象):
private GifImage gifImage = null;
private string filePath = @"C:'Users'Jeremy'Desktop'ExampleAnimation.gif";
public Form1()
{
InitializeComponent();
//a) Normal way
//pictureBox1.Image = Image.FromFile(filePath);
//b) We control the animation
gifImage = new GifImage(filePath);
gifImage.ReverseAtEnd = false; //dont reverse at end
}
private void button1_Click(object sender, EventArgs e)
{
//Start the time/animation
timer1.Enabled = true;
}
//The event that is animating the Frames
private void timer1_Tick(object sender, EventArgs e)
{
pictureBox1.Image = gifImage.GetNextFrame();
}
其次,要知道您要运行GIF图像多长时间,您可能需要像这样获取GIF图像的帧持续时间:
double delayIn10Ms; //declare somewhere
//Initialize on your form load
PropertyItem item = img.GetPropertyItem (0x5100); // FrameDelay in libgdiplus
// Time is in 1/100th of a second
delayIn10Ms = (item.Value [0] + item.Value [1] * 256) * 10;
然后利用delayIn10Ms
时间加上可能更多的时间来停止计时器。您可能还想检查计时器上次滴答的时间并存储它。如果它超过了给定的延迟时间,那么您应该停止计时器并在掷骰子时再次启动它,在您的switch
情况下进行图像分配。
DateTime currentTick = DateTime.Min;
DateTime startTick = DateTime.Min;
private void timer1_Tick(object sender, EventArgs e)
{
currentTick = DateTime.Now;
if ((currentTick - startTick).TotalSeconds / 100 < delayIn10Ms)
pictureBox1.Image = gifImage.GetNextFrame();
else
timer1.Stop(); //stop the timer
}
//And somewhere else you have
timer1.Start(); //to start the timer
int x = rollDice(); //Here I roll the dice
switch (x){
case 1: dice.Image = resources.diceFace1; //Image set depending on x
break
case 2: //etc...
}
您可以使用将 Interval 属性设置为动画长度的计时器,并将其 Tag 设置为 0,然后在计时器中编写代码:
if(timer.Tag == "0")
timer.Tag == "1";
else if(timer.Tag == "1")
{
int x = rollDice();
switch (x)
{
case 1: dice.Image = resources.diceFace1; break;
case 2: //etc...
}
timer.Tag == "0";
timer.Stop();
}