public static void CreateAnimatedGif(List <string> gifFiles, int delay, string outputFile) { BinaryWriter writer = new BinaryWriter(new FileStream(outputFile, FileMode.Create, FileAccess.ReadWrite)); byte[] gif_Signature = new byte[] { (byte)'G', (byte)'I', (byte)'F', (byte)'8', (byte)'9', (byte)'a' }; writer.Write(gif_Signature); for (int i = 0; i < gifFiles.Count; i++) { GifClass gif = new GifClass(); gif.LoadGifPicture(gifFiles[i]); if (i == 0) { writer.Write(gif.m_ScreenDescriptor.ToArray()); } writer.Write(GifCreator.CreateGraphicControlExtensionBlock(delay)); writer.Write(gif.m_ImageDescriptor.ToArray()); writer.Write(gif.m_ColorTable.ToArray()); writer.Write(gif.m_ImageData.ToArray()); } writer.Write(GifCreator.CreateLoopBlock()); writer.Write((byte)0x3B); //End file writer.Close(); }
private void WriteAnimatedGif(Bitmap src, Stream output, IEncoder ios, ResizeSettings queryString) { //http://www.fileformat.info/format/gif/egff.htm //http://www.fileformat.info/format/gif/spec/44ed77668592476fb7a682c714a68bac/view.htm //Heavily modified and patched from comments on http://bloggingabout.net/blogs/rick/archive/2005/05/10/3830.aspx MemoryStream memoryStream = null; BinaryWriter writer = null; //Variable declaration try { writer = new BinaryWriter(output); memoryStream = new MemoryStream(4096); //Write the GIF 89a sig writer.Write(new byte[] { (byte)'G', (byte)'I', (byte)'F', (byte)'8', (byte)'9', (byte)'a' }); //We parse this from the source image int loops = GetLoops(src.PropertyItems); int[] delays = GetDelays(src.PropertyItems);//20736 (delays) 20737 (loop); int frames = src.GetFrameCount(FrameDimension.Time); for (int frame = 0; frame < frames; frame++) { //Select the frame src.SelectActiveFrame(FrameDimension.Time, frame); // http://radio.weblogs.com/0122832/2005/10/20.html //src.MakeTransparent(); This call makes some GIFs replicate the first image on all frames.. i.e. SelectActiveFrame doesn't work. bool transparent = ios.SupportsTransparency; using (Bitmap b = c.CurrentImageBuilder.Build(src, queryString, false)){ //Useful to check if animation is occurring - sometimes the problem isn't the output file, but the input frames are //all the same. //for (var i = 0; i < b.Height; i++) b.SetPixel(frame * 10, i, Color.Green); // b.Save(memoryStream, ImageFormat.Gif); if (ios is DefaultEncoder) { //For both WIC Builder and DefaultBuilder //We assume no transparency transparent = false; } ios.Write(b, memoryStream); //Allows quantization and dithering } GifClass gif = new GifClass(); gif.LoadGifPicture(memoryStream); if (frame == 0) { //Only one screen descriptor per file. Steal from the first image writer.Write(gif.m_ScreenDescriptor.ToArray()); //How many times to loop the image (unless it is 1) IE and FF3 loop endlessly if loop=1 if (loops != 1) { writer.Write(GifCreator.CreateLoopBlock(loops)); } } //Restore frame delay int delay = 0; if (delays != null && delays.Length > frame) { delay = delays[frame]; } writer.Write(GifCreator.CreateGraphicControlExtensionBlock(delay, 0, transparent)); //The delay/transparent color block writer.Write(gif.m_ImageDescriptor.ToArray()); //The image desc writer.Write(gif.m_ColorTable.ToArray()); //The palette writer.Write(gif.m_ImageData.ToArray()); //Image data memoryStream.SetLength(0); //Clear the mem stream, but leave it allocated for now memoryStream.Seek(0, SeekOrigin.Begin); //Reset memory buffer } writer.Write((byte)0x3B); //End file } finally { if (memoryStream != null) { memoryStream.Dispose(); } //if (writer != null) writer.Close } }