// -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) James South. // Licensed under the Apache License, Version 2.0. // // // Provides the necessary information to support gif images. // // -------------------------------------------------------------------------------------------------------------------- namespace ImageProcessor.Imaging.Formats { using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Text; using ImageProcessor.Core.Common.Extensions; /// /// Provides the necessary information to support gif images. /// public class GifFormat : FormatBase { /// /// Gets the file header. /// public override byte[] FileHeader { get { return Encoding.ASCII.GetBytes("GIF"); } } /// /// Gets the list of file extensions. /// public override string[] FileExtensions { get { return new[] { "gif" }; } } /// /// Gets the standard identifier used on the Internet to indicate the type of data that a file contains. /// public override string MimeType { get { return "image/gif"; } } /// /// Gets the . /// public override ImageFormat ImageFormat { get { return ImageFormat.Gif; } } /// /// Applies the given processor the current image. /// /// The processor delegate. /// The . public override void ApplyProcessor(Func processor, ImageFactory factory) { ImageInfo imageInfo = factory.Image.GetImageInfo(this.ImageFormat); if (imageInfo.IsAnimated) { OctreeQuantizer quantizer = new OctreeQuantizer(255, 8); // We don't dispose of the memory stream as that is disposed when a new image is created and doing so // beforehand will cause an exception. MemoryStream stream = new MemoryStream(); using (GifEncoder encoder = new GifEncoder(stream, null, null, imageInfo.LoopCount)) { foreach (GifFrame frame in imageInfo.GifFrames) { factory.Image = frame.Image; frame.Image = quantizer.Quantize(processor.Invoke(factory)); encoder.AddFrame(frame); } } stream.Position = 0; factory.Image = Image.FromStream(stream); } else { base.ApplyProcessor(processor, factory); } } /// /// Saves the current image to the specified output stream. /// /// /// The to save the image information to. /// /// The to save. /// /// The . /// public override Image Save(MemoryStream memoryStream, Image image) { // TODO: Move this in here. It doesn't need to be anywhere else. ImageInfo imageInfo = image.GetImageInfo(this.ImageFormat, false); if (!imageInfo.IsAnimated) { image = new OctreeQuantizer(255, 8).Quantize(image); } return base.Save(memoryStream, image); } /// /// Saves the current image to the specified file path. /// /// The path to save the image to. /// The /// to save. /// /// The . /// public override Image Save(string path, Image image) { // TODO: Move this in here. It doesn't need to be anywhere else. ImageInfo imageInfo = image.GetImageInfo(this.ImageFormat, false); if (!imageInfo.IsAnimated) { image = new OctreeQuantizer(255, 8).Quantize(image); } return base.Save(path, image); } } }