一旦gif结束,如何更改图片框

时间:2016-02-20 18:33:23

标签: c# animation resources visual-studio-2015 picturebox

我有一个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...
}

2 个答案:

答案 0 :(得分:1)

可能需要做两件事。

首先,您可能需要确保PictureBox收到gif图像并且知道它。为此,请检查this answerthis answer。这些帖子的代码可以逐帧显示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图像的时间,您可能需要Get Frame Duration of GIF image这样:

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...
}

答案 1 :(得分:0)

您可以创建一个定时器,将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();
}