在同事的博客上面看到一个关于用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素材,金馆长...- -!