WPF播放GIF控件完整代码

原创 2016年09月14日 09:38:14

WPF拥有很强的界面设计能力,可以很方便的做出非常漂亮的界面。但有个问题,WPF没有自己的播放GIF的控件。这让很多想在界面播放动态动画的人不得不使用视频来代替。WPF就真的不能播放GIF动图了吗?当然是可以播放的,只是我们需要写一些代码。下面是我总结后写的一个WPF播放GIF动画的控件。

下面介绍一下WPF播放GIF控件思路:

在WinForm里面System.Drawing.Bitmap是可以通过ImageAnimator类来播放GIF动画的,但是可惜的是System.Drawing.Bitmap没有办法直接显示在WPF界面上。于是我们利用ImageAnimator播放System.Drawing.Bitmap对应的GIF动画。在每次System.Drawing.Bitmap上显示的图像改变时,获取当前图像,然后将图像转换为可以在WPF上显示BitmapSource,将转换得来的BitmapSource作为一帧动画显示在界面。

首先我们建立一个命名为GifImage的类,这个类继承自System.Windows.Controls.Image。它的作用就是将System.Drawing.Bitmap转换后得到的BitmapSource赋值给继承自Image控件的Source属性,来显示GIF图像,当GIF每一帧的图像改变时,GifImage显示的内容也会改变,这样就达到了动态效果。下面是代码,很简单。

public class GifImage : System.Windows.Controls.Image
    {
        /// <summary>
        /// gif动画的System.Drawing.Bitmap
        /// </summary>
        private Bitmap gifBitmap;

        /// <summary>
        /// 用于显示每一帧的BitmapSource
        /// </summary>
        private BitmapSource bitmapSource;

        public GifImage(string gifPath)
        {
            this.gifBitmap = new Bitmap(gifPath);
            this.bitmapSource = this.GetBitmapSource();
            this.Source = this.bitmapSource;
        }

        /// <summary>
        /// 从System.Drawing.Bitmap中获得用于显示的那一帧图像的BitmapSource
        /// </summary>
        /// <returns></returns>
        private BitmapSource GetBitmapSource()
        {
            IntPtr handle = IntPtr.Zero;

            try
            {
                handle = this.gifBitmap.GetHbitmap();
                this.bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(handle, IntPtr.Zero, System.Windows.Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
            }
            finally
            {
                if (handle != IntPtr.Zero)
                {
                    DeleteObject(handle);
                }
            }

            return this.bitmapSource;
        }

        /// <summary>
        /// Start animation
        /// </summary>
        public void StartAnimate()
        {
            ImageAnimator.Animate(this.gifBitmap, this.OnFrameChanged);
        }

        /// <summary>
        /// Stop animation
        /// </summary>
        public void StopAnimate()
        {
            ImageAnimator.StopAnimate(this.gifBitmap, this.OnFrameChanged);
        }

        /// <summary>
        /// Event handler for the frame changed
        /// </summary>
        private void OnFrameChanged(object sender, EventArgs e)
        {
            Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(()=> 
            {
                ImageAnimator.UpdateFrames();  // 更新到下一帧
                if (this.bitmapSource != null)
                {
                    this.bitmapSource.Freeze();
                }

                //// Convert the bitmap to BitmapSource that can be display in WPF Visual Tree
                this.bitmapSource = this.GetBitmapSource();
                Source = this.bitmapSource;
                this.InvalidateVisual();
            }));
        }

        /// <summary>
        /// Delete local bitmap resource
        /// Reference: http://msdn.microsoft.com/en-us/library/dd183539(VS.85).aspx
        /// </summary>
        [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool DeleteObject(IntPtr hObject);

    }

其中ImageAnimator类是通过静态方法Animate和StopAnimate开始和结束System.Drawing.Bitmap所对应的GIF动画。这两个函数的第二个参数是一个委托,当前播放GIF动画每一帧图像发生改变的时候,这个委托所指定的函数就会被触发。那么我们就可以在这个委托里将当前显示的System.Drawing.Bitmap图像转换为在WPF上可以显示的BitmapSource,然后赋值给Source属性显示在界面。

下面是在一个Window中使用GIFInage控件。ProgressIndicator.gif是要播放的GIF文件的文件名,在程序运行目录。

public partial class MainWindow : Window
    {
        private GifImage gifImage; 

        public MainWindow()
        {
            InitializeComponent();
            this.gifImage = new GifImage("ProgressIndicator.gif");
            this.gifImage.Width = 100;
            this.gifImage.Height = 100;
            this.Content = this.gifImage;
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            this.gifImage.StartAnimate();
        }
    }



代码下载地址:http://download.csdn.net/detail/libby1984/9637803



版权声明:本文为博主原创文章,未经博主允许不得转载。

WPF 如何显示gif

最近碰到了要显示表情的需求,而表情刚好是gif的图片。 于是用了Image试了下,发现不行,只会显示第一帧,然后上网查了下资料,大致有这么几种方法,都可以实现。 第一种: 使用Winfrom里面的pi...
  • wcc27857285
  • wcc27857285
  • 2016年11月01日 09:52
  • 2431

【C#】wpf添加gif动图支持

1.nuget里下载WpfAnimatedGif包,然后安装。 2.添加WpfAnimatedGif包的命名空间:xmlns:gif="http://wpfanimatedgif.codeplex.c...
  • catshitone
  • catshitone
  • 2017年06月08日 17:21
  • 1665

WPF 显示gif

  • 2014年02月28日 16:07
  • 711KB
  • 下载

WPF使用MediaElement显示gif图片

使用MediaElement来显示gif图片,封装控件代码如下: Xaml:
  • SANYUNI
  • SANYUNI
  • 2017年06月22日 17:12
  • 397

WPF播放GIF

  • 2016年09月23日 10:46
  • 78KB
  • 下载

在Wpf中使用动态GIF图像的简单方法

Wpf本身的方法如果加载GIF实在是过于复杂,我们可以通过使用winform控件,减少复杂性方法一:利用winform控件 System.Windows.Forms. PictureBox pb ...
  • u012790747
  • u012790747
  • 2015年05月27日 21:26
  • 1768

C# WPF按钮控件动态加载图片

在WPF的xaml文件中图片按钮实现: 在C#代码中:Uri uri = new Uri(Config.CellImage, UriKind.RelativeOrA...
  • hhhhhjkk
  • hhhhhjkk
  • 2017年10月18日 18:58
  • 269

wpf加载gif动态图片

  • 2013年03月25日 16:22
  • 813KB
  • 下载

当WPF遇到了gif

WPF很强大,但是当WPF的image控件遇到gif时就只读了图片的第一帧,很好很强大!  WPF不屑于gif的简单动画!  但是这对程序员来说不大爽啊!急得我眼泪都下来了!  幸好WPF里有Medi...
  • zhang98722
  • zhang98722
  • 2010年12月07日 10:12
  • 2542

GIF Image Control For WPF

  • 2014年08月08日 16:20
  • 324KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:WPF播放GIF控件完整代码
举报原因:
原因补充:

(最多只允许输入30个字)