Devesprit.ImageProcessor & Devesprit.ImageServer
Extending Supported File Formats

ISupportedImageFormat

It is also possible to extend the image formats that Devesprit.ImageProcessor is capable of manipulating by providing a new class implementing the ISupportedImageFormat interface. Devesprit.ImageProcessor will automatically search all assemblies in Application directory to find classes implementing that interface when initializing.

ISupportedImageFormat.cs
Copy Code
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace Devesprit.ImageProcessor.Imaging.Formats
{
    /// <summary>
    /// The SupportedImageFormat interface providing information about image formats to ImageProcessor.
    /// </summary>
    public interface ISupportedImageFormat
    {
        /// <summary>
        /// Gets the list of file extensions.
        /// </summary>
        string[] FileExtensions { get; }

        /// <summary>
        /// Gets the standard identifier used on the Internet to indicate the type of data that a file contains.
        /// </summary>
        string MimeType { get; }

        /// <summary>
        /// Gets the default file extension.
        /// </summary>
        string DefaultExtension { get; }

        /// <summary>
        /// Gets the file format of the image.
        /// </summary>
        ImageFormat ImageFormat { get; }

        /// <summary>
        /// Gets or sets a value indicating whether the image format is indexed.
        /// </summary>
        bool IsIndexed { get; set; }

        /// <summary>
        /// Gets or sets the quality of output for images.
        /// </summary>
        int Quality { get; set; }

        /// <summary>
        /// Applies the given processor the current image.
        /// </summary>
        /// <param name="processor">
        /// The processor delegate.
        /// </param>
        /// <param name="factory">
        /// The <see cref="ImageFactory"/>.
        /// </param>
        void ApplyProcessor(Func<ImageFactory, Image> processor, ImageFactory factory);

        /// <summary>
        /// Loads the image to process.
        /// </summary>
        /// <param name="stream">
        /// The <see cref="T:System.IO.Stream"/> containing the image information.
        /// </param>
        /// <returns>
        /// The <see cref="T:System.Drawing.Image"/>.
        /// </returns>
        Image Load(Stream stream);

        /// <summary>
        /// Saves the current image to the specified output stream.
        /// </summary>
        /// <param name="stream">
        /// The <see cref="T:System.IO.Stream"/> to save the image information to.
        /// </param>
        /// <param name="image">
        /// The <see cref="T:System.Drawing.Image"/> to save.
        /// </param>
        /// <param name="bitDepth">
        /// The color depth in number of bits per pixel to save the image with.
        /// </param>
        /// <returns>
        /// The <see cref="T:System.Drawing.Image"/>.
        /// </returns>
        Image Save(Stream stream, Image image, long bitDepth);

        /// <summary>
        /// Saves the current image to the specified file path.
        /// </summary>
        /// <param name="path">The path to save the image to.</param>
        /// <param name="image">
        /// The <see cref="T:System.Drawing.Image"/> to save.
        /// </param>
        /// <param name="bitDepth">
        /// The color depth in number of bits per pixel to save the image with.
        /// </param>
        /// <returns>
        /// The <see cref="T:System.Drawing.Image"/>.
        /// </returns>
        Image Save(string path, Image image, long bitDepth);

        /// <summary>
        /// Detect input stream is a valid image for current format
        /// </summary>
        /// <param name="stream">
        /// The <see cref="T:System.IO.Stream"/> containing the image information.
        /// </param>
        /// <returns>If image format is valid then return True.</returns>
        bool CanLoadStream(Stream stream);
    }
}

Example

BitmapFormat.cs
Copy Code
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
namespace Devesprit.ImageProcessor.Imaging.Formats
{
    /// <summary>
    /// Provides the necessary information to support bitmap images.
    /// </summary>
    public class BitmapFormat : ISupportedImageFormat
    {
        /// <summary>
        /// Gets the default file extension.
        /// </summary>
        public string DefaultExtension => "bmp";

        /// <summary>
        /// Gets or sets a value indicating whether the image format is indexed.
        /// </summary>
        public bool IsIndexed { get; set; }

        /// <summary>
        /// Gets or sets the quality of output for images.
        /// </summary>
        public int Quality { get; set; }

        /// <summary>
        /// Gets the list of file extensions.
        /// </summary>
        public string[] FileExtensions => new[]
        {
            "bmp"
        };

        /// <summary>
        /// Gets the standard identifier used on the Internet to indicate the type of data that a file contains.
        /// </summary>
        public string MimeType => "image/bmp";

        /// <summary>
        /// Gets the <see cref="ImageFormat" />.
        /// </summary>
        public ImageFormat ImageFormat => ImageFormat.Bmp;

        /// <summary>
        /// Initializes a new instance of the <see cref="BitmapFormat"/> class.
        /// </summary>
        protected BitmapFormat()
        {
            this.Quality = 90;
        }

        /// <summary>
        /// Detect input stream is a valid image for current format
        /// </summary>
        /// <param name="stream">
        /// The <see cref="T:System.IO.Stream"/> containing the image information.
        /// </param>
        /// <returns>If image format is valid then return True.</returns>
        public bool CanLoadStream(Stream stream)
        {
            //Check Stream Magic Number
            byte[][] fileHeaders =
            {
                Encoding.ASCII.GetBytes("BM")
            };
            int numberOfBytesToRead = fileHeaders.Max(h => h.Length);
            byte[] buffer = new byte[numberOfBytesToRead];
            stream.Read(buffer, 0, buffer.Length);
            foreach (byte[] header in fileHeaders)
            {
                if (header.SequenceEqual(buffer.Take(header.Length)))
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// Applies the given processor the current image.
        /// </summary>
        /// <param name="processor">The processor delegate.</param>
        /// <param name="factory">The <see cref="ImageFactory" />.</param>
        public void ApplyProcessor(Func<ImageFactory, Image> processor, ImageFactory factory)
        {
            factory.Image = processor.Invoke(factory);
        }

        /// <summary>
        /// Decodes the image to process.
        /// </summary>
        /// <param name="stream">
        /// The <see cref="T:System.IO.stream" /> containing the image information.
        /// </param>
        /// <returns>
        /// The <see cref="T:System.Drawing.Image" />.
        /// </returns>
        public Image Load(Stream stream)
        {
            // Keep the colors but don't validate the data. The windows decoders are robust.
            return Image.FromStream(stream, true, false);
        }

        /// <summary>
        /// Saves the current image to the specified output stream.
        /// </summary>
        /// <param name="stream">
        /// The <see cref="T:System.IO.Stream"/> to save the image information to.
        /// </param>
        /// <param name="image">
        /// The <see cref="T:System.Drawing.Image"/> to save.
        /// </param>
        /// <param name="bitDepth">
        /// The color depth in number of bits per pixel to save the image with.
        /// </param>
        /// <returns>
        /// The <see cref="T:System.Drawing.Image"/>.
        /// </returns>
        public Image Save(Stream stream, Image image, long bitDepth)
        {
            image.Save(stream, this.ImageFormat);
            return image;
        }

        /// <summary>
        /// Saves the current image to the specified file path.
        /// </summary>
        /// <param name="path">The path to save the image to.</param>
        /// <param name="image">
        /// The <see cref="T:System.Drawing.Image"/> to save.
        /// </param>
        /// <param name="bitDepth">
        /// The color depth in number of bits per pixel to save the image with.
        /// </param>
        /// <returns>
        /// The <see cref="T:System.Drawing.Image"/>.
        /// </returns>
        public Image Save(string path, Image image, long bitDepth)
        {
            image.Save(path, this.ImageFormat);
            return image;
        }
    }
}