我目前正在尝试在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();
}
}
}
答案 0 :(得分:3)
不幸的是,当微软开发WPF时,动画GIF图像有点疏忽,所以没有内置的&#39;处理这个的功能。在线发现了几个工作示例,但您仍应注意,需要在UI线程上运行代码才能为这些图像设置动画。
因此,在某些情况下,例如尝试使用“忙碌”等。加载过程中的GIF将无法正常工作,因为UI线程已经忙碌。
宣布免责声明之后,您可以在以下链接中找到一些可以在Thomas Levesque的GitHub项目中执行您想要的工作代码:
答案 1 :(得分:2)
使用线程
public MainWindow()
{
InitializeComponent();
Uri myUri = new Uri(@"Images\2b3601fe2b62e87481bd301da52a2182.gif", UriKind.RelativeOrAbsolute);
GifBitmapDecoder decoder2 = new GifBitmapDecoder(myUri, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource bitmapSource2;
int frameCount = decoder2.Frames.Count;
Thread th = new Thread(() => {
while (true)
{
for (int i = 0; i < frameCount; i++)
{
this.Dispatcher.Invoke(new Action(delegate()
{
bitmapSource2 = decoder2.Frames[i];
image.Source = bitmapSource2;
}));
System.Threading.Thread.Sleep(100);
}
}
});
th.Start();
}
答案 2 :(得分:0)
这仅适用于未编译为资源等的物理文件
尝试更改您的图像资源Build Action to Content或类似内容,而不是资源(并激活Copy to Output Directory,可能?)。
我设法以这种方式工作。关键是你必须引用某个文件夹或互联网URL中的物理文件。