C#实现拆分、合并GIF图片

    在同事的博客上面看到一个关于用C#拆分跟合并GIF图片的文章,不过看完发现只是写了如何拆分GIF图片而已- -!由于自己也感兴趣于是找了一下相关资料,自己敲了点代码,记录一番先。

    首先看下把GIF图片拆分成多张JPG的代码。C#.NET中提供的Image类结合FrameDimension类其实已经可以做到这一点了,具体代码如下(这里我是写了一个WinForm查询来测试,是在一个名为button1的按钮中实现这一功能的):

c#代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/// <summary>
/// 拆分GIF(使用.Net框架的Image对象)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
    var imgFileName = @"E:\temp\jgz.gif"; // gif图片的全名(物理路径)
    var imgSaveDir = @"E:\temp\jgz_images"; // 存放拆分后的图片的文件夹
    var re = ""; // 用于保存操作结果的变量
    try
    {
        Image imgGif = Image.FromFile(imgFileName); // 获取图片对象
        // 先判断图片是否是动画图片(gif)
        if (ImageAnimator.CanAnimate(imgGif))
        {
            // 查看存放图片的目录是否存在,不存在的话就创建该目录
            if (!Directory.Exists(imgSaveDir))
            {
                Directory.CreateDirectory(imgSaveDir);
            }
            FrameDimension imgFrmDim = new FrameDimension(imgGif.FrameDimensionsList[0]);
            int nFdCount = imgGif.GetFrameCount(imgFrmDim); // 获取帧数
            for (int i = 0; i < nFdCount; i++)
            {
                // 把每一帧保存为jpg图片
                imgGif.SelectActiveFrame(imgFrmDim, i);
                var imgSaveName = Path.Combine(imgSaveDir, string.Format("jgz{0}.jpg", i + 1));
                imgGif.Save(imgSaveName, ImageFormat.Jpeg);
            }
            re = string.Format("分解成功,请查看目录 {0}", imgSaveDir);
        }
        else
        {
            re = "不是动画图片(gif)";
        }
    }
    catch (Exception ex)
    {
        re = ex.Message;
    }
    MessageBox.Show(re);
}

    以上的代码算是比较完整的,包括try...catch已经对gif图片的验证(验证是否是动画图片),前提是在E:\temp\ 这个目录下有一张文件名为jgz.gif的gif格式的图片,具体的看代码注释就ok了^_^。


    对于把多张图片合并为GIF的,C#.NET似乎没有提供相应的类来完成(也许是我out了,如果您知道有的话,请告诉我^_^)。在网上找了一下,找到这个组件Gif.Components。这个组件提供了两个重要的类,一个是AnimatedGifEncoder类,用于把多个图片合成GIF;另外一个是GifDecoder类,用于把GIF拆分成多个图片(提供了一种更为简单的方法)。

    直接上代码,和上面一样,也是在按钮的点击事件中完成任务(代码尽量简单,所以也不作出错验证了,只实现需要的功能):

c#代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/// <summary>
/// 合成GIF(使用Gif.Components组件的AnimatedGifEncoder)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
    string re = ""; // 用于保存操作结果的变量
    try
    {
        string[] jpgImgNames = Directory.GetFiles(@"E:\temp\jgz_images"); // 获取各帧图片的文件名
        string dtStr = DateTime.Now.ToString("yyyyMMddhhmmss");
        string outPutPath = string.Format(@"E:\temp\jgz{0}.gif", dtStr); // 生成要保存成的gif图片的文件名
        // 创建动画(gif)
        AnimatedGifEncoder animate = new AnimatedGifEncoder();
        animate.Start(outPutPath);
        animate.SetDelay(150);
        animate.SetRepeat(0); // -1:不重复,0:无限循环
        foreach (var item in jpgImgNames)
        {
            Image imgFrame = Image.FromFile(item);
            animate.AddFrame(imgFrame); // 添加帧
        }
        animate.Finish();
        re = "生成成功,请查看" + outPutPath;
    }
    catch (Exception ex)
    {
        re = ex.Message;
    }
    MessageBox.Show(re);
}

 

c#代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/// <summary>
/// 拆分GIF(使用Gif.Components组件)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button3_Click(object sender, EventArgs e)
{
    var imgFileName = @"E:\temp\jgz.gif"; // gif图片的全名(物理路径)
    var imgSaveDir = @"E:\temp\jgz_images"; // 存放拆分后的图片的文件夹
    var re = ""; // 用于保存操作结果的变量
    try
    {
        GifDecoder decoder = new GifDecoder();
        decoder.Read(imgFileName);
        int frameCount = decoder.GetFrameCount(); // 获取帧数
        for (int i = 0; i < frameCount; i++)
        {
            Image frameImg = decoder.GetFrame(i);
            var imgSaveName = Path.Combine(imgSaveDir, string.Format("jgz{0}.jpg", i + 1));
            frameImg.Save(imgSaveName, ImageFormat.Jpeg);
        }
        re = string.Format("分解成功,请查看目录 {0}", imgSaveDir);
    }
    catch (Exception ex)
    {
        re = ex.Message;
    }
    MessageBox.Show(re);
}


    以上两段代码分别是合并和拆分GIF,但是......使用的时候发现效果不佳 - -@,如果您有更好的组件介绍或者实现方法,请麻烦告知我哇^_^。

    PS:以上代码需要引入的命名空间:

c#代码
1
2
3
4
5
6
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using Gif.Components;



    这里献上两个资源,首先是组件:Gif.Components.rar,另外一个是gif素材,金馆长...- -!
    

      

 

posted @ 2012-07-13 10:18  serafin  阅读(2684)  评论(2)    收藏  举报