C# PictureBox 可以在 Windows 应用程序中显示动画 GIF 吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13485477/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 08:43:04  来源:igfitidea点击:

Can a PictureBox show animated GIF in Windows Application?

c#.netvb.netanimationanimated-gif

提问by Angela

I would like to show a animated gif in .Net Winform. How to do this?

我想在 .Net Winform 中显示动画 gif。这该怎么做?

I previously used VB 6.0.

我以前使用过 VB 6.0。

回答by Jeremy Thompson

  1. Put a PictureBoxon a form and then specify a picture file with a Gif extension. Or:

  2. Programatically animate a gif Image loading frames into a PictureBoxwith code, here's the Gif class:

  1. 将 aPictureBox放在表单上,​​然后指定带有 Gif 扩展名的图片文件。或者:

  2. 以编程方式将 gif 图像加载到PictureBox带有代码的图像中,这是 Gif 类:

VB.NET

网络

Public Class GifImage
    Private gifImage As Image
    Private dimension As FrameDimension
    Private frameCount As Integer
    Private currentFrame As Integer = -1
    Private reverse As Boolean
    Private [step] As Integer = 1

    Public Sub New(path As String)
        gifImage = Image.FromFile(path)
        'initialize
        dimension = New FrameDimension(gifImage.FrameDimensionsList(0))
        'gets the GUID
            'total frames in the animation
        frameCount = gifImage.GetFrameCount(dimension)
    End Sub

    Public Property ReverseAtEnd() As Boolean
        'whether the gif should play backwards when it reaches the end
        Get
            Return reverse
        End Get
        Set
            reverse = value
        End Set
    End Property

    Public Function GetNextFrame() As Image

        currentFrame += [step]

        'if the animation reaches a boundary...
        If currentFrame >= frameCount OrElse currentFrame < 0 Then
            If reverse Then
                [step] *= -1
                '...reverse the count
                    'apply it
                currentFrame += [step]
            Else
                currentFrame = 0
                '...or start over
            End If
        End If
        Return GetFrame(currentFrame)
    End Function

    Public Function GetFrame(index As Integer) As Image
        gifImage.SelectActiveFrame(dimension, index)
        'find the frame
        Return DirectCast(gifImage.Clone(), Image)
        'return a copy of it
    End Function
End Class

C#

C#

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 < 0) {
            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
    }
}

C# usage:

C#用法:

Open a Winform project drag and drop in a PictureBox, a Timer and a Button, with the GifImage.csthe class is shown above.

打开一个 Winform 项目,拖放一个PictureBox,一个 Timer 和一个 Button,GifImage.cs类如上所示。

public partial class Form1: Form
{
    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();
    }
}

enter image description here

在此处输入图片说明

回答by matei.navidad

Developing on @JeremyThompson's answer I would like to add a code snippet to show how you can implement the first approach, because it is a lot simpler, and does not require you to manually animate the gif, seeing that the PictureBoxhas a built-in feature to handle such a scenario. Just add a PictureBoxto your form, and in the form constructor assign the image path to the PictureBox.ImageLocation

根据@JeremyThompson 的回答进行开发我想添加一个代码片段来展示如何实现第一种方法,因为它简单得多,并且不需要您手动为 gif 设置动画,因为它PictureBox具有内置功能来处理这样的场景。只需PictureBox在您的表单中添加一个,并在表单构造函数中将图像路径分配给PictureBox.ImageLocation

C#

C#

 public PictureForm()
 {
      InitializeComponent();
      pictureBoxGif.ImageLocation = "C:\throbber.gif";
 }

VB.Net

VB.Net

Public Sub New()
    InitializeComponent()
    pictureBoxGif.ImageLocation = "C:\throbber.gif"
End Sub

In my oppinion this is a much simpler solution, especially for someone who is new to .NET.

在我看来,这是一个更简单的解决方案,特别是对于 .NET 的新手。

回答by sober

I've played around with this and the animation plays provided that you don't perform another long running operation on the same thread. The moment you perform another long running operation, you'd want to do it in another thread.

我已经玩过这个并且动画播放,前提是您不在同一线程上执行另一个长时间运行的操作。当您执行另一个长时间运行的操作时,您希望在另一个线程中执行它。

The simplest way to do this, is to use the BackgroundWorker component that you can drag onto the form from your toolbox. You'd then put your long running operation code in the DoWork() event of the BackgroundWorker. The final step would be to invoke your code by calling the RunWorkerAsync() method of the BackgroundWorker instance.

最简单的方法是使用 BackgroundWorker 组件,您可以将其从工具箱拖到表单上。然后,您将长时间运行的操作代码放在 BackgroundWorker 的 DoWork() 事件中。最后一步是通过调用 BackgroundWorker 实例的 RunWorkerAsync() 方法来调用您的代码。