C#实现拆分、合并GIF图片
在同事的博客上面看到一个关于用C#拆分跟合并GIF图片的文章,不过看完发现只是写了如何拆分GIF图片而已- -!由于自己也感兴趣于是找了一下相关资料,自己敲了点代码,记录一番先。
首先看下把GIF图片拆分成多张JPG的代码。C#.NET中提供的Image类结合FrameDimension类其实已经可以做到这一点了,具体代码如下(这里我是写了一个WinForm查询来测试,是在一个名为button1的按钮中实现这一功能的):
|
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拆分成多个图片(提供了一种更为简单的方法)。
直接上代码,和上面一样,也是在按钮的点击事件中完成任务(代码尽量简单,所以也不作出错验证了,只实现需要的功能):
|
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);} |
|
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:以上代码需要引入的命名空间:
|
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素材,金馆长...- -!

浙公网安备 33010602011771号