在Silverlight中我们可以使用ImageTools库的AnimatedImage控件来播放GIF图片,但是AnimatedImage目前还不支持WinRT应用,所以我实现了一个简单的控件来播放本地GIF文件。原理很蛋疼,首先用各种工具把GIF拆成单独的PNG文件,然后放到同一个文件夹下面,加载到内存中后用Timer来控制循环显示。

代码实现
public sealed class GifImage : ContentControl
{
    private readonly Image _image = new Image();
    private BitmapImage[] _bitmapList;
    private int _bitmapIndex;
    private readonly DispatcherTimer _timerController = new DispatcherTimer();

    public GifImage()
    {
        _timerController.Tick += timerController_Tick;
        _image.Stretch = Stretch.None;
        Content = _image;
    }

    public async void Init(string msappxPath, string extension, uint count, uint intervalMs)
    {
        _bitmapList = new BitmapImage[count];

        if (!extension.StartsWith("."))
            extension = "." + extension;

        string[] pathList = msappxPath.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
        StorageFolder installFolder = Package.Current.InstalledLocation;
        StorageFolder sfImage = installFolder;
        for (int i = 0; i < pathList.Length; i++)
            sfImage = await sfImage.GetFolderAsync(pathList[i]);

        for (int i = 0; i < count; i++)
        {
            StorageFile fileImage = await sfImage.GetFileAsync(i + extension);
            using (var stream = await fileImage.OpenReadAsync())
            {
                _bitmapList[i] = new BitmapImage();
                _bitmapList[i].SetSource(stream);
            }
        }

        _timerController.Interval = TimeSpan.FromMilliseconds(intervalMs);
        _timerController.Start();
    }

    public void Unload()
    {
        _timerController.Tick -= timerController_Tick;
        _timerController.Stop();
        _image.Source = null;
        for (int i = 0; i < _bitmapList.Length; i++)
            _bitmapList[i] = null;
    }

    public void Pause()
    {
        _timerController.Stop();
    }

    public void Resume()
    {
        _timerController.Start();
    }

    private void timerController_Tick(object sender, object e)
    {
        if (_bitmapIndex == _bitmapList.Length - 1)
            _bitmapIndex = 0;
        else
            _bitmapIndex++;
        _image.Source = _bitmapList[_bitmapIndex];
    }
}
使用方法

把PNG图片用Content方式加到项目中后,在对应页面的构造函数中调用Init()方法:

_gifImg.Init("/Assets/Gif/", "png", 5, 100);

在必要的地方调用Pause()和Resume()方法来控制播放,调用Unload()方法来释放资源。

» 转载请注明来源及链接:未来代码研究所

Related Posts:

6 Responses to “Windows Phone 8.1应用移植手记3:实现本地GIF动画播放”

Leave a Reply

World Line
Time Machine
Online Tools