c# - 在 WPF 中播放 Gif

标签 c# wpf

我目前正在尝试在 WPF 中显示和播放动画 gif,但运气不佳

我已经尝试了找到的所有解决方案 here包括问题中的那个

这是我目前拥有的

<Window x:Class="Sooooothing.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Attached="clr-namespace:Sooooothing"
    Title="MainWindow" Height="327.861" Width="525">
<Grid>
    <MediaElement x:Name="gif" MediaEnded="myGif_MediaEnded" UnloadedBehavior="Manual" 
                  Source="Images\7c6516d73fc8643abf1df969fcc1a72c.gif" 
                  LoadedBehavior="Play" Stretch="None"/>
</Grid>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Sooooothing
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            //gif.Play();
        }
        private void myGif_MediaEnded(object sender, RoutedEventArgs e)
        {
            gif.Position = new TimeSpan(0, 0, 1);
            gif.Play();
        }
    }
}

当应用程序启动时,我得到的只是窗口的白色背景,起初我以为是 gif 没有加载,但我让它静置几分钟,没有任何变化。

这是我的解决方案

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Sooooothing
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        GifBitmapDecoder decoder2;
        int ImageNumber = 0;
        bool mouseIn = true;
        double opasity = 0;
        List<Thread> threadList = new List<Thread>();
        bool programClosed = false;
        public MainWindow()
        {
            InitializeComponent();

            Classes.DataHouse.load(); //Im storing all my gif links in this List<string> so i can 
            // loop through them with buttons on the window

            #region thread gif frame changer
            Uri myUri = new Uri(Classes.DataHouse.images[ImageNumber], UriKind.RelativeOrAbsolute);
            decoder2 = new GifBitmapDecoder(myUri, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
            BitmapSource bitmapSource2; // Decode the gif using GifBitmapDecoder then start a thread to 
            int frameCount = decoder2.Frames.Count;// loop through all the images and put them one after
            Thread th = new Thread(() => {// another into an image on your window
                while (!programClosed)
                {

                    for (int i = 0; i < frameCount; i++)
                    {
                        try{
                            this.Dispatcher.Invoke(new Action(delegate()
                            {
                                frameCount = decoder2.Frames.Count;
                                if (frameCount >= i)
                                {
                                    bitmapSource2 = decoder2.Frames[i];
                                    image.Source = bitmapSource2;
                                }

                            }));
                        }
                        catch
                        {
                            //the thread was probably aborted
                        }
                        System.Threading.Thread.Sleep(100);
                    }
                }
            });
            threadList.Add(th);
            th.Start();
            #endregion
        }

        private void Window_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ChangedButton == MouseButton.Left)
                this.DragMove();
        }

        private void img_forward_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (ImageNumber+1 >= Classes.DataHouse.images.Count)
                ImageNumber = 0;
            else
                ImageNumber++;
            Uri myUri = new Uri(Classes.DataHouse.images[ImageNumber], UriKind.RelativeOrAbsolute);
            decoder2 = new GifBitmapDecoder(myUri, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
        }

        private void Grid_MouseEnter(object sender, MouseEventArgs e)
        {
            mouseIn = true;
            Thread th = new Thread(() => 
            {
                while (opasity < 100 && mouseIn)
                {
                    System.Threading.Thread.Sleep(25);
                    opasity++;
                    try
                    {
                        this.Dispatcher.Invoke(new Action(delegate()
                        {
                            img_forward.Opacity = opasity / 100;
                            img_exit.Opacity = opasity / 100;
                            img_backward.Opacity = opasity / 100;
                        }));
                    }
                    catch
                    {
                        //the thread was probably aborted
                    }
                }
            });
            threadList.Add(th);
            th.Start();


        }

        private void Grid_MouseLeave(object sender, MouseEventArgs e)
        {
            mouseIn = false;
            Thread th = new Thread(() =>
            {

                while (opasity > 0 && !mouseIn)
                {
                    System.Threading.Thread.Sleep(25);
                    opasity--;
                    try{
                        this.Dispatcher.Invoke(new Action(delegate()
                        {
                            img_forward.Opacity = opasity / 100;
                            img_exit.Opacity = opasity / 100;
                            img_backward.Opacity = opasity / 100;
                        }));
                    }
                    catch
                    {
                        //the thread was probably aborted
                    }
                }
            });
            threadList.Add(th);
            th.Start();
        }

        private void img_backward_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (ImageNumber - 1 < 0)
                ImageNumber = Classes.DataHouse.images.Count-1;
            else
                ImageNumber--;
            Uri myUri = new Uri(Classes.DataHouse.images[ImageNumber], UriKind.RelativeOrAbsolute);
            decoder2 = new GifBitmapDecoder(myUri, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
        }

        private void img_exit_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            foreach (Thread th in threadList)
            {
                while(th.ThreadState == ThreadState.Running)
                    th.Abort();
            }
            programClosed = true;
            this.Close();
        }

    }
}

最佳答案

不幸的是,在 Microsoft 开发 WPF 时,动画 GIF 图像在某种程度上是一个疏忽,因此没有处理此问题的“内置”功能。在网上找到了几个有效的示例,但您仍然应该知道代码需要在 UI 线程上运行才能为这些图像设置动画。

因此,某些情况下,例如在加载期间尝试使用“繁忙”的 GIF 将无法正常工作,因为 UI 线程已经很忙了。

宣布该免责声明后,您可以在 Thomas Levesque 的 GitHub 项目中找到一些工作代码来执行您想要的操作,链接如下:

thomaslevesque/WpfAnimatedGif

关于c# - 在 WPF 中播放 Gif,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30803184/

相关文章:

c# - 基于特定属性的 Entity Framework 预加载

c# - 将动态数字格式插入内插字符串

wpf - 将 DataGridColumn 的 Width 属性绑定(bind)到父 DataGrid 的 ActualWidth

带有 DataGrid 的 WPF 应用程序中的 C# 搜索框

c# - 使用 Eval Boolean 为 asp.net 控件设置样式

c# - WCF Silverlight HTTP 和 HTTPS

c# - 很难用字典回答自学作业

c# - 完全删除 "App.xaml"并创建自己的入口点,后果是什么?

c# - Open/SaveFileDialog 类之间的区别及其在 WPF 窗体中的使用

c# - 我应该考虑从 WPF 切换到 Silverlight 吗?