// -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) James South. // Licensed under the Apache License, Version 2.0. // // // Utility methods for working with supported image formats. // // -------------------------------------------------------------------------------------------------------------------- namespace ImageProcessor.Imaging.Formats { using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Reflection; using System.Threading.Tasks; using ImageProcessor.Configuration; /// /// Utility methods for working with supported image formats. /// public static class FormatUtilities { /// /// Gets the correct from the given stream. /// /// /// /// The to read from. /// /// /// The . /// public static ISupportedImageFormat GetFormat(Stream stream) { // Reset the position of the stream to ensure we're reading the correct part. stream.Position = 0; IEnumerable supportedImageFormats = ImageProcessorBootstrapper.Instance.SupportedImageFormats; byte[] buffer = new byte[4]; stream.Read(buffer, 0, buffer.Length); foreach (ISupportedImageFormat supportedImageFormat in supportedImageFormats) { byte[][] headers = supportedImageFormat.FileHeaders; // ReSharper disable once LoopCanBeConvertedToQuery foreach (byte[] header in headers) { if (header.SequenceEqual(buffer.Take(header.Length))) { stream.Position = 0; // Return a new instance as we want to use instance properties. return Activator.CreateInstance(supportedImageFormat.GetType()) as ISupportedImageFormat; } } } stream.Position = 0; return null; } /// /// Returns a value indicating whether the given image is indexed. /// /// /// The to test. /// /// /// The true if the image is indexed; otherwise, false. /// public static bool IsIndexed(Image image) { // Test value of flags using bitwise AND. // ReSharper disable once BitwiseOperatorOnEnumWithoutFlags return (image.PixelFormat & PixelFormat.Indexed) != 0; } /// /// Returns the color count from the palette of the given image. /// /// /// The to get the colors from. /// /// /// The representing the color count. /// public static int GetColorCount(Image image) { ConcurrentDictionary colors = new ConcurrentDictionary(); int width = image.Width; int height = image.Height; using (FastBitmap fastBitmap = new FastBitmap(image)) { Parallel.For( 0, height, y => { for (int x = 0; x < width; x++) { // ReSharper disable once AccessToDisposedClosure Color color = fastBitmap.GetPixel(x, y); colors.TryAdd(color, color); } }); } int count = colors.Count; colors.Clear(); return count; } /// /// Returns a value indicating whether the given image is indexed. /// /// /// The to test. /// /// /// The true if the image is animated; otherwise, false. /// public static bool IsAnimated(Image image) { return ImageAnimator.CanAnimate(image); } /// /// Returns an instance of EncodingParameters for jpeg compression. /// /// The quality to return the image at. /// The encodingParameters for jpeg compression. public static EncoderParameters GetEncodingParameters(int quality) { EncoderParameters encoderParameters = null; try { // Create a series of encoder parameters. encoderParameters = new EncoderParameters(1); // Set the quality. encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, quality); } catch { if (encoderParameters != null) { encoderParameters.Dispose(); } } return encoderParameters; } /// /// Uses reflection to allow the creation of an instance of . /// /// /// The . /// public static PropertyItem CreatePropertyItem() { Type type = typeof(PropertyItem); ConstructorInfo constructor = type.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, new Type[] { }, null); return (PropertyItem)constructor.Invoke(null); } } }