// -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) James South. // Licensed under the Apache License, Version 2.0. // // // Extends the ImageFactory class to provide a fluent API. // // -------------------------------------------------------------------------------------------------------------------- namespace ImageProcessor.Web { #region Using using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; using ImageProcessor.Extensions; using ImageProcessor.Imaging; using ImageProcessor.Processors; using ImageProcessor.Web.Config; #endregion /// /// Extends the ImageFactory class to provide a fluent API. /// public static class ImageFactoryExtensions { /// /// The object to lock against. /// private static readonly object SyncRoot = new object(); /// /// Auto processes image files based on any query string parameters added to the image path. /// /// /// The current instance of the class /// that this method extends. /// /// /// The current instance of the class. /// public static ImageFactory AutoProcess(this ImageFactory factory) { if (factory.ShouldProcess) { // It's faster to lock and run through our activated list than to create new instances. lock (SyncRoot) { // Get a list of all graphics processors that have parsed and matched the query string. List graphicsProcessors = ImageProcessorConfig.Instance.GraphicsProcessors .Where(x => x.MatchRegexIndex(factory.QueryString) != int.MaxValue) .OrderBy(y => y.SortOrder) .ToList(); // Loop through and process the image. foreach (IGraphicsProcessor graphicsProcessor in graphicsProcessors) { ApplyProcessor(graphicsProcessor.ProcessImage, factory); } } } return factory; } /// /// Processes the image. /// /// /// The processor. /// /// /// The factory. /// private static void ApplyProcessor(Func processor, ImageFactory factory) { ImageInfo imageInfo = factory.Image.GetImageInfo(factory.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.Update(frame.Image); frame.Image = quantizer.Quantize(processor.Invoke(factory)); encoder.AddFrame(frame); } } stream.Position = 0; factory.Update(Image.FromStream(stream)); } else { factory.Update(processor.Invoke(factory)); } // Set the property item information from any Exif metadata. // We do this here so that they can be changed between processor methods. if (factory.PreserveExifData) { foreach (KeyValuePair propertItem in factory.ExifPropertyItems) { try { factory.Image.SetPropertyItem(propertItem.Value); } // ReSharper disable once EmptyGeneralCatchClause catch { // Do nothing. The image format does not handle EXIF data. // TODO: empty catch is fierce code smell. } } } } } }