Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

GIF Animation in WPF

0.00/5 (No votes)
6 May 2013 1  
A library which provides an option to play animated Sprite sheets.

Introduction

GIF images cannot be used directly in a WPF application. There are lot of third party libraries which support GIF images in WPF. Here is one which could play animated sprite sheets in WPF.

Background

If you are good with WPF custom controls, Dispatcher timer, and Render Transforms, you are ready to read this tip.

Using the Code

We have a custom control which contains an image control in which the Source property is bound to the ImageSource property. The user will set the Sprite sheet image source to this property.

<Style TargetType="{x:Type local:Animator}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:Animator}">
                    <Grid >
                        <Canvas Background="{TemplateBinding Background}"
                            x:Name="PART_Border" HorizontalAlignment="Center"
                                VerticalAlignment="Center">
 
                            <Image Source="{TemplateBinding ImageSource}"
                               Stretch="UniformToFill" x:Name="PART_Image">
 
                            </Image>
                        </Canvas>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style> 

Normally a Sprite sheet can be horizontal or vertical or both (with rows and columns). A small portion of the sprite image will be exposed by clipping it. We used the HorizontalOffset and VerticalOffset properties to decide the Clip rect.

private void SetRect()
{
    if (_image != null)
    {
        _border.Clip = new RectangleGeometry(new Rect(0, 0, HorizontalOffset, VerticalOffset));
        _border.Height = VerticalOffset;
        _border.Width = HorizontalOffset;
        
        if (HorizontalOffset > 0.0)
            _maxHpieces = Convert.ToInt16(_image.ActualWidth / HorizontalOffset);
            
        if (VerticalOffset > 0.0)
            _maxVpieces = Convert.ToInt16(_image.ActualHeight / VerticalOffset);
    }
} 

Choosing the offset values is the only challenge here. It simply defines the size of each image in the Sprite map. We are going to change the translate transform based on the offset values at a specific interval. Since we already clipped a particular portion of the image based on the offset, it gives an impression of animation.

void Animator_Loaded(object sender, RoutedEventArgs e)
{
    _timer = new DispatcherTimer(Interval, DispatcherPriority.Normal, Callback, Dispatcher);
    SetRect();
    Loaded -= Animator_Loaded;
    Unloaded += Animator_Unloaded;
    _timer.Start();
    
}

private void Callback(object sender, EventArgs eventArgs)
{
    _Hcount++;
    if (_Hcount >= _maxHpieces)
    {
        _Hcount = 0;
        _Vcount++;
        if (_Vcount >= _maxVpieces)
        {
            _Vcount = 0;
        }
    }
    _image.RenderTransform = new TranslateTransform
    	(-HorizontalOffset * _Hcount, -VerticalOffset * _Vcount);
} 

The offset values may change based on the size of the sprite image. I have attached a demo which contains the various sizes of Sprite images.

Points of Interest

There are many online tools and sites which convert GIF images to Sprite images. The following one looks good:

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here