10

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

I previously used VB 6.0.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Angela
  • 111
  • 2
  • 2
  • 9
  • for animated an image you can use this controller. http://www.codeproject.com/Tips/1004624/Gif-viewer-Snipper-control – xwpedram Jun 27 '15 at 21:19

3 Answers3

25
  1. Put a PictureBox on a form and then specify a picture file with a Gif extension. Or:

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

VB.NET

 Imports System.Drawing.Imaging
 Imports System.Drawing

 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#

using System.Drawing.Imaging;
using System.Drawing;

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:

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

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

Jeremy Thompson
  • 61,933
  • 36
  • 195
  • 321
20

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 PictureBox has a built-in feature to handle such a scenario. Just add a PictureBox to your form, and in the form constructor assign the image path to the PictureBox.ImageLocation

C#

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

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.

matei.navidad
  • 676
  • 6
  • 18
  • 3
    +1 for sportsmanship, **if only things were this easy in VB6**. The `joy of .Net`, really, as I continue to grow I notice how much better a managed framework is!!! – Jeremy Thompson Mar 17 '13 at 13:22
  • +1 to give relevance to your solution, simple and perfect. Please note that disabling picture box (or the form) will block the animation of the gif! – Marco Jan 28 '15 at 14:12
  • Another thing I had issues with is "C:\\throbber.gif" can be simplified to @"C:\throbber.gif" this helped me combine larger directories and avoid issues with combining directories as strings. [More info](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/verbatim) – Caleb Laws Jun 26 '23 at 17:23
1

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.

sober
  • 99
  • 1
  • 2