WPF跑GIF文件的方法

注:本工程来codeproject

WPF默认的IMAGE是无法让GIF文件动起来的。

下面为一种可以让GIF在WPF中动起来的办法。

关键还在AnimatedGIFControl.cs文件中。

WPF跑GIF文件的方法

  1. /****************************** Module Header ******************************\
  2. Module Name:    AnimatedGIFControl.cs
  3. Project:     CSWPFAnimatedGIF
  4. Copyright (c) Microsoft Corporation.

  5. The CSWPFAnimatedGIF demonstrates how to implement
  6. an animated GIF image in WPF.

  7. This source is subject to the Microsoft Public License.
  8. See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
  9. All other rights reserved.

  10. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
  11. EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
  12. WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
  13. \***************************************************************************/

  14. using System;
  15. using System.Drawing;
  16. using System.Runtime.InteropServices;
  17. using System.Windows;
  18. using System.Windows.Interop;
  19. using System.Windows.Media.Imaging;
  20. using System.Windows.Threading;

  21. namespace CSWPFAnimatedGIF
  22. {
  23.     public class AnimatedGIFControl : System.Windows.Controls.Image
  24.     {
  25.         private Bitmap _bitmap; // Local bitmap member to cache image resource
  26.         private BitmapSource _bitmapSource;
  27.         public delegate void FrameUpdatedEventHandler();
  28.             

  29.         ///
  30.         /// Delete local bitmap resource
  31.         /// Reference: http://msdn.microsoft.com/en-us/library/dd183539(VS.85).aspx
  32.         ///
  33.         [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  34.         static extern bool DeleteObject(IntPtr hObject);

  35.         ///
  36.         /// Override the OnInitialized method
  37.         ///
  38.         protected override void OnInitialized(EventArgs e)
  39.         {
  40.             base.OnInitialized(e);
  41.             this.Loaded += new RoutedEventHandler(AnimatedGIFControl_Loaded);
  42.             this.Unloaded += new RoutedEventHandler(AnimatedGIFControl_Unloaded);
  43.         }

  44.         ///
  45.         /// Load the embedded image for the Image.Source
  46.         ///
  47.         void AnimatedGIFControl_Loaded(object sender, RoutedEventArgs e)
  48.         {
  49.             // Get GIF image from Resources
  50.             if (Properties.Resources.ProgressIndicator != null)
  51.             {
  52.                 _bitmap = Properties.Resources.ProgressIndicator;
  53.                 Width = _bitmap.Width;
  54.                 Height = _bitmap.Height;

  55.                 _bitmapSource = GetBitmapSource();
  56.                 Source = _bitmapSource;
  57.             }
  58.         }

  59.         ///
  60.         /// Close the FileStream to unlock the GIF file
  61.         ///
  62.         private void AnimatedGIFControl_Unloaded(object sender, RoutedEventArgs e)
  63.         {
  64.             StopAnimate();
  65.         }

  66.         ///
  67.         /// Start animation
  68.         ///
  69.         public void StartAnimate()
  70.         {
  71.             ImageAnimator.Animate(_bitmap, OnFrameChanged);
  72.         }

  73.         ///
  74.         /// Stop animation
  75.         ///
  76.         public void StopAnimate()
  77.         {
  78.             ImageAnimator.StopAnimate(_bitmap, OnFrameChanged);
  79.         }

  80.         ///
  81.         /// Event handler for the frame changed
  82.         ///
  83.         private void OnFrameChanged(object sender, EventArgs e)
  84.         {
  85.             Dispatcher.BeginInvoke(DispatcherPriority.Normal,
  86.                                    new FrameUpdatedEventHandler(FrameUpdatedCallback));
  87.         }

  88.         private void FrameUpdatedCallback()
  89.         {
  90.             ImageAnimator.UpdateFrames();

  91.             if (_bitmapSource != null)
  92.                 _bitmapSource.Freeze();

  93.             // Convert the bitmap to BitmapSource that can be display in WPF Visual Tree
  94.             _bitmapSource = GetBitmapSource();
  95.             Source = _bitmapSource;
  96.             InvalidateVisual();
  97.         }

  98.         private BitmapSource GetBitmapSource()
  99.         {
  100.             IntPtr handle = IntPtr.Zero;

  101.             try
  102.             {
  103.                 handle = _bitmap.GetHbitmap();
  104.                 _bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(
  105.                     handle, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
  106.             }
  107.             finally
  108.             {
  109.                 if (handle != IntPtr.Zero)
  110.                     DeleteObject(handle);
  111.             }

  112.             return _bitmapSource;
  113.         }

  114.     }
  115. }


测试工程代码:
WPF跑GIF文件的方法Show GIF animation in WPF (CSWPFAnimatedGIF).rar