更新:
我做更多的研究,我想這些的ffmpeg和mplayer的建議是值得一試:
Create animated gif from a set of jpeg images
更新2:
這從Rick van den Bosch代碼是非常也可以,因爲它可以讓您訪問延遲時間:
.net(至少1.1,他們可能將它合併到2.0中)不會給你 通過GDI +創建動畫GIF的可能性。
//Variable declaration
StringCollection stringCollection;
MemoryStream memoryStream;
BinaryWriter binaryWriter;
Image image;
Byte[] buf1;
Byte[] buf2;
Byte[] buf3;
//Variable declaration
stringCollection = a_StringCollection_containing_images;
Response.ContentType = "Image/gif";
memoryStream = new MemoryStream();
buf2 = new Byte[19];
buf3 = new Byte[8];
buf2[0] = 33; //extension introducer
buf2[1] = 255; //application extension
buf2[2] = 11; //size of block
buf2[3] = 78; //N
buf2[4] = 69; //E
buf2[5] = 84; //T
buf2[6] = 83; //S
buf2[7] = 67; //C
buf2[8] = 65; //A
buf2[9] = 80; //P
buf2[10] = 69; //E
buf2[11] = 50; //2
buf2[12] = 46; //.
buf2[13] = 48; //0
buf2[14] = 3; //Size of block
buf2[15] = 1; //
buf2[16] = 0; //
buf2[17] = 0; //
buf2[18] = 0; //Block terminator
buf3[0] = 33; //Extension introducer
buf3[1] = 249; //Graphic control extension
buf3[2] = 4; //Size of block
buf3[3] = 9; //Flags: reserved, disposal method, user input, transparent color
buf3[4] = 10; //Delay time low byte
buf3[5] = 3; //Delay time high byte
buf3[6] = 255; //Transparent color index
buf3[7] = 0; //Block terminator
binaryWriter = new BinaryWriter(Response.OutputStream);
for (int picCount = 0; picCount < stringCollection.Count; picCount++)
{
image = Bitmap.FromFile(stringCollection[picCount]);
image.Save(memoryStream, ImageFormat.Gif);
buf1 = memoryStream.ToArray();
if (picCount == 0)
{
//only write these the first time....
binaryWriter.Write(buf1, 0, 781); //Header & global color table
binaryWriter.Write(buf2, 0, 19); //Application extension
}
binaryWriter.Write(buf3, 0, 8); //Graphic extension
binaryWriter.Write(buf1, 789, buf1.Length - 790); //Image data
if (picCount == stringCollection.Count - 1)
{
//only write this one the last time....
binaryWriter.Write(";"); //Image terminator
}
memoryStream.SetLength(0);
}
binaryWriter.Close();
Response.End();
正如漢斯提到其不支持,所以這第三個解決方案是RenniePet的建議提取來自gif文件的幀,然後所有的幀結合在一起。
添加對System.Drawing的引用。DLL並使用此代碼來獲取幀:
using System.Drawing;
using System.Drawing.Imaging;
public class GifImage
{
private Image gifImage;
private FrameDimension dimension;
private int frameCount;
private int currentFrame = -1;
private bool reverse;
private int step = 1;
public GifImage(string path)
{
gifImage = Image.FromFile(path);
//initialize
dimension = new FrameDimension(gifImage.FrameDimensionsList[0]);
//gets the GUID
//total frames in the animation
frameCount = gifImage.GetFrameCount(dimension);
}
public int GetFrameCount()
{
return frameCount;
}
public bool ReverseAtEnd
{
//whether the gif should play backwards when it reaches the end
get { return reverse; }
set { reverse = value; }
}
public Image GetNextFrame()
{
currentFrame += step;
//if the animation reaches a boundary...
if (currentFrame >= frameCount || currentFrame < 1)
{
if (reverse)
{
step *= -1;
//...reverse the count
//apply it
currentFrame += step;
}
else
{
currentFrame = 0;
//...or start over
}
}
return GetFrame(currentFrame);
}
public Image GetFrame(int index)
{
gifImage.SelectActiveFrame(dimension, index);
//find the frame
return (Image)gifImage.Clone();
//return a copy of it
}
}
我們可以提取所有的幀是這樣的:使用
private static readonly string tempFolder = @"C:\temp\";
static void Main(string[] args)
{
CombineGifs(@"c:\temp\a.gif", @"c:\temp\b.gif");
}
public static void CombineGifs(string firstImageFilePath, string secondImageFilePath)
{
int frameCounter = ExtractGifFramesAndGetCount(firstImageFilePath, 0);
int secondframeCounter = ExtractGifFramesAndGetCount(secondImageFilePath, frameCounter);
string filePathOfCombinedGif = CombineFramesIntoGif(0, secondframeCounter);
}
private static int ExtractGifFramesAndGetCount(string filePath, int imageNameStartNumber)
{
////NGif had an error when I tried it
//GifDecoder gifDecoder = new GifDecoder();
//gifDecoder.Read(filePath);
//int frameCounter = imageNameStartNumber + gifDecoder.GetFrameCount();
//for (int i = imageNameStartNumber; i < frameCounter; i++)
//{
// Image frame = gifDecoder.GetFrame(i); // frame i
// frame.Save(tempFolder + i.ToString() + ".png", ImageFormat.Png);
//}
//So we'll use the Gifimage implementation
GifImage gifImage = new GifImage(filePath);
gifImage.ReverseAtEnd = false;
int frameCounter = imageNameStartNumber + gifImage.GetFrameCount();
for (int i = imageNameStartNumber; i < frameCounter; i++)
{
Image img = gifImage.GetNextFrame();
img.Save(tempFolder + i.ToString() + ".png");
}
return frameCounter;
}
接下來,我們所有的幀合併成一個gif動畫NGif
下載代碼,打開解決方案並編譯Components項目以獲取DLL Gif.Components.dll
並在您的解決方案中引用該DLL。
private static string CombineFramesIntoGif(int startFrameCount, int endFrameCount)
{
List<string> imageFilePaths = new List<string>();
for (int i = startFrameCount; i < endFrameCount; i++)
{
imageFilePaths.Add(tempFolder + i.ToString() + ".png");
}
string outputFilePath = tempFolder + "test.gif";
AnimatedGifEncoder e = new AnimatedGifEncoder();
e.Start(outputFilePath);
e.SetDelay(500);
//-1:no repeat,0:always repeat
e.SetRepeat(0);
for (int i = 0; i < imageFilePaths.Count; i++)
{
e.AddFrame(Image.FromFile(imageFilePaths[i]));
}
e.Finish();
return outputFilePath;
}
它只是不被內置在GDI +中的gif編碼器支持。你無法完成這項工作。 –
真的嗎?這是真的嗎? –
好,愚蠢的問題,但只是要確定:你在談論動畫GIF,對吧? – RenniePet