如何在WPF中将多个PNG图像呈现为GIF?

huangapple go评论54阅读模式
英文:

How to present multiple PNG images as GIF in wpf?

问题

我正在研究一个WPF项目。
我有40个带有透明背景的PNG文件,当我将它们拼在一起时,它们就像一个自然的加载条一样工作。我不想将它制作成GIF,而是像以PNG格式加载UI中的某些内容。

我尝试过的方法如下:

  1. 使用UI线程进行重复实现:我发现资源消耗非常大,被认为不适合使用。
  2. WpfAnimatedGif库:被认为不适合使用所需的40个PNG文件。

如果您有任何好的想法,请回复。

英文:

I studying a wpf project.
I have 40 PNG files with transparent backgrounds, and when I stitch them together, they work like a natural loading bar. I don't want to make it into a GIF, but rather like loading something into the UI in PNG format.

The attempts I've made are as follows:

  1. Repetitive implementation using UI Thread: I found a huge consumption of resources. It is considered unsuitable.
  2. WpfAnimatedGif library: It is considered inappropriate to use the desired 40 PNG files.

If you have any good ideas, please reply.

答案1

得分: 0

假设您在XAML中有一个名为imageImage元素,并且您的PNG文件的路径存储在名为imagePathsList<string>中,您可以使用一个定时器:

private void UpdateLoadingBar()
{
    var frameIndex = 0;
    var frameCount = imagePaths.Count;

    var timer = new DispatcherTimer();
    timer.Interval = TimeSpan.FromMilliseconds(100);
    timer.Tick += (sender, e) =>
    {
        loadingImage.Source = new BitmapImage(
            new Uri(imagePaths[frameIndex], UriKind.RelativeOrAbsolute));

        if (++frameIndex >= frameCount)
        {
            // Stop the timer when all frames have been displayed
            timer.Stop();
        }
    };

    timer.Start();
}

或者,如果您熟悉异步编程,您可以使用:

private async Task UpdateLoadingBar()
{
    foreach (var imagePath in imagePaths)
    {
        loadingImage.Source = new BitmapImage(
            new Uri(imagePath, UriKind.RelativeOrAbsolute));

        // Delay between each frame (adjust the duration as needed)
        await Task.Delay(100);
    }
}

这需要从异步事件处理程序中启动,例如:

private async void StartLoadingButton_Click(object sender, RoutedEventArgs e)
{
    await UpdateLoadingBar();
}
英文:

Assuming you have in your XAML an Image element named image and your paths to the png files in a List<string> named imagePaths you can use a timer:

private void UpdateLoadingBar()
{
    var frameIndex = 0;
    var frameCount = imagePaths.Count;
        
    var timer = new DispatcherTimer();
    timer.Interval = TimeSpan.FromMilliseconds(100);
    timer.Tick += (sender, e) =>
    {
        loadingImage.Source = new BitmapImage(
            new Uri(imagePaths[frameIndex], UriKind.RelativeOrAbsolute));

        if (++frameIndex >= frameCount)
        {
            // Stop the timer when all frames have been displayed
            timer.Stop();
        }
    };

    timer.Start();
}

Or if you are familiar with async programming you could use

private async Task UpdateLoadingBar()
{
    foreach (var imagePath in imagePaths)
    {
        loadingImage.Source = new BitmapImage(
            new Uri(imagePath, UriKind.RelativeOrAbsolute));

        // Delay between each frame (adjust the duration as needed)
        await Task.Delay(100);
    }
}

This needs to be started from an async event handler like:

private async void StartLoadingButton_Click(object sender, RoutedEventArgs e)
{
    await UpdateLoadingBar();
}

huangapple
  • 本文由 发表于 2023年6月19日 11:03:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/76503375.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定