白帽子舒克 2021-04-19 16:08 采纳率: 0%
浏览 9

C# 下载网络上的GIF图片的时候,怎么保持动画效果?

下载网络上GIF图片,发现没有动画效果,怎么能把gif图片完整的保存下来呢?

  • 写回答

1条回答 默认 最新

  • Design JBY 2023-05-01 18:39
    关注

    在 C# 中下载 GIF 图片,应该使用 WebClient 进行下载。但是需要注意的是,WebClient 默认只下载 GIF 图片的第一帧,而不是整个动画。如果你想下载整个 GIF 图片,需要使用更高级的方法。

    一种方法是使用 HttpWebRequest 手动下载整个 GIF 文件,然后解析文件中的每一帧图像,最终将它们合并为一个 GIF 动画。这个过程需要用到 ImageFrameDimension 类,可以参考下面的代码示例:

    using System.Drawing;
    using System.Drawing.Imaging;
    using System.IO;
    using System.Net;
    
    public void DownloadGif(string url, string savePath)
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    
        Bitmap animatedGif;
    
        using (Stream responseStream = response.GetResponseStream())
        {
            Image image = Image.FromStream(responseStream);
    
            FrameDimension dimension = new FrameDimension(image.FrameDimensionsList[0]);
            int frameCount = image.GetFrameCount(dimension);
    
            int delay = 0;
    
            using (MemoryStream memoryStream = new MemoryStream())
            {
                image.Save(memoryStream, ImageFormat.Gif);
                animatedGif = (Bitmap)Image.FromStream(memoryStream);
            }
    
            for (int i = 0; i < frameCount; i++)
            {
                image.SelectActiveFrame(dimension, i);
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    image.Save(memoryStream, ImageFormat.Gif);
                    Image frame = Image.FromStream(memoryStream);
                    FrameDimension frameDimension = new FrameDimension(frame.FrameDimensionsList[0]);
                    FrameDelayProperty frameDelay = (FrameDelayProperty)frame.GetPropertyItem(20736);
    
                    if (frameDelay != null)
                    {
                        var byteArray = frameDelay.Value;
                        var numerator = BitConverter.ToInt32(byteArray, 0);
                        var denominator = BitConverter.ToInt32(byteArray, 4);
    
                        if (denominator == 0)
                        {
                            delay += numerator * 10;
                        }
                        else
                        {
                            delay += numerator * 10 / denominator;
                        }
                    }
                    else
                    {
                        delay = 100;
                    }
    
                    animatedGif.SaveAdd(frame, frameDimension, Encoder.SaveFlag);
                }
            }
        }
    
        response.Close();
        animatedGif.Save(savePath, ImageFormat.Gif);
    }
    

    使用这个方法下载 GIF 图片时,需要将 savePath 参数设置为保存图片的路径,例如:"C:\test.gif"。

    另一种方法是使用开源的 GifskiSharp 库,它可以将一系列图像转化为 GIF 动画。你可以使用 HttpClient 下载 GIF 图片并将其转换为字节数组,然后将字节数组转换为位图列表,最后使用 GifskiSharp 将其保存为 GIF 动画。这个过程需要使用异步操作,示例代码如下:

    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.IO;
    using System.Linq;
    using System.Net.Http;
    using System.Threading.Tasks;
    using GifskiSharp;
    
    public async Task DownloadAndSaveAnimatedGifAsync(string url, string savePath)
    {
        HttpClient httpClient = new HttpClient();
        HttpResponseMessage httpResponse = await httpClient.GetAsync(url);
    
        byte[] gifBytes = await httpResponse.Content.ReadAsByteArrayAsync();
    
        Image gifImage = Image.FromStream(new MemoryStream(gifBytes));
        FrameDimension dimension = new FrameDimension(gifImage.FrameDimensionsList[0]);
        int frameCount = gifImage.GetFrameCount(dimension);
    
        List<Bitmap> bitmaps = new List<Bitmap>();
    
        for (int i = 0; i < frameCount; i++)
        {
            gifImage.SelectActiveFrame(dimension, i);
            bitmaps.Add(new Bitmap(gifImage));
        }
    
        var encoder = new GifskiEncoder(new GifskiEncoderOptions { Quality = 100 });
        encoder.AddFrames(bitmaps.Select(bmp => bmp.ToByteArray(ImageFormat.Png, 100)).ToArray());
        encoder.Finish();
    
        File.WriteAllBytes(savePath, encoder.Encode());
    }
    

    这个方法使用了 GifskiSharp 库,可以使用 NuGet 包管理器安装。

    无论使用哪种方法,都需要注意 GIF 图片的大小和下载速度,以避免程序出现性能问题。此外,下载和处理 GIF 图片时可能会使用到较大的内存,也需要注意内存管理。

    评论

报告相同问题?

悬赏问题

  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 matlab有关常微分方程的问题求解决
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算
  • ¥15 java如何提取出pdf里的文字?
  • ¥100 求三轴之间相互配合画圆以及直线的算法
  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考