How do I get an animated gif to work in WPF?

前端 未结 18 955
广开言路
广开言路 2020-11-22 12:16

What control type should I use - Image, MediaElement, etc.?

18条回答
  •  情话喂你
    2020-11-22 12:22

    I have try all the way above, but each one has their shortness, and thanks to all you, I work out my own GifImage:

        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
        using System.Windows.Controls;
        using System.Windows;
        using System.Windows.Media.Imaging;
        using System.IO;
        using System.Windows.Threading;
    
        namespace IEXM.Components
        {
        public class GifImage : Image
        {
                #region gif Source, such as "/IEXM;component/Images/Expression/f020.gif"
                public string GifSource
                {
                        get { return (string)GetValue(GifSourceProperty); }
                        set { SetValue(GifSourceProperty, value); }
                }
    
                public static readonly DependencyProperty GifSourceProperty =
                        DependencyProperty.Register("GifSource", typeof(string),
                        typeof(GifImage), new UIPropertyMetadata(null, GifSourcePropertyChanged));
    
                private static void GifSourcePropertyChanged(DependencyObject sender,
                        DependencyPropertyChangedEventArgs e)
                {
                        (sender as GifImage).Initialize();
                }
                #endregion
    
                #region control the animate
                /// 
                /// Defines whether the animation starts on it's own
                /// 
                public bool IsAutoStart
                {
                        get { return (bool)GetValue(AutoStartProperty); }
                        set { SetValue(AutoStartProperty, value); }
                }
    
                public static readonly DependencyProperty AutoStartProperty =
                        DependencyProperty.Register("IsAutoStart", typeof(bool),
                        typeof(GifImage), new UIPropertyMetadata(false, AutoStartPropertyChanged));
    
                private static void AutoStartPropertyChanged(DependencyObject sender,
                        DependencyPropertyChangedEventArgs e)
                {
                        if ((bool)e.NewValue)
                                (sender as GifImage).StartAnimation();
                        else
                                (sender as GifImage).StopAnimation();
                }
                #endregion
    
                private bool _isInitialized = false;
                private System.Drawing.Bitmap _bitmap;
                private BitmapSource _source;
    
                [System.Runtime.InteropServices.DllImport("gdi32.dll")]
                public static extern bool DeleteObject(IntPtr hObject);
    
                private BitmapSource GetSource()
                {
                        if (_bitmap == null)
                        {
                                _bitmap = new System.Drawing.Bitmap(Application.GetResourceStream(
                                         new Uri(GifSource, UriKind.RelativeOrAbsolute)).Stream);
                        }
    
                        IntPtr handle = IntPtr.Zero;
                        handle = _bitmap.GetHbitmap();
    
                        BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                                handle, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                        DeleteObject(handle);
                        return bs;
                }
    
                private void Initialize()
                {
                //        Console.WriteLine("Init: " + GifSource);
                        if (GifSource != null)
                                Source = GetSource();
                        _isInitialized = true;
                }
    
                private void FrameUpdatedCallback()
                {
                        System.Drawing.ImageAnimator.UpdateFrames();
    
                        if (_source != null)
                        {
                                _source.Freeze();
                        }
    
                   _source = GetSource();
    
                  //  Console.WriteLine("Working: " + GifSource);
    
                        Source = _source;
                        InvalidateVisual();
                }
    
                private void OnFrameChanged(object sender, EventArgs e)
                {
                        Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(FrameUpdatedCallback));
                }
    
                /// 
                /// Starts the animation
                /// 
                public void StartAnimation()
                {
                        if (!_isInitialized)
                                this.Initialize();
    
    
                 //   Console.WriteLine("Start: " + GifSource);
    
                        System.Drawing.ImageAnimator.Animate(_bitmap, OnFrameChanged);
                }
    
                /// 
                /// Stops the animation
                /// 
                public void StopAnimation()
                {
                        _isInitialized = false;
                        if (_bitmap != null)
                        {
                                System.Drawing.ImageAnimator.StopAnimate(_bitmap, OnFrameChanged);
                                _bitmap.Dispose();
                                _bitmap = null;
                        }
                        _source = null;
                        Initialize();
                        GC.Collect();
                        GC.WaitForFullGCComplete();
    
                 //   Console.WriteLine("Stop: " + GifSource);
                }
    
                public void Dispose()
                {
                        _isInitialized = false;
                        if (_bitmap != null)
                        {
                                System.Drawing.ImageAnimator.StopAnimate(_bitmap, OnFrameChanged);
                                _bitmap.Dispose();
                                _bitmap = null;
                        }
                        _source = null;
                        GC.Collect();
                        GC.WaitForFullGCComplete();
                   // Console.WriteLine("Dispose: " + GifSource);
                }
        }
    }
    

    Usage:

    
    

    As it would not cause memory leak and it animated the gif image own time line, you can try it.

提交回复
热议问题