static void

ImageResizer

Create high quality thumbnails (the same code as this helper class used in an IHttpHandler) with jpeg compression.

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
 
namespace Library.Images
{
    /// <summary>
    /// Resize images
    /// </summary>
    public class ImageResizer
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ImageResizer"/> class.
        /// </summary>
        /// <param name="fromPath">From path.</param>
        /// <param name="toPath">To path.</param>
        public ImageResizer(string fromPath, string toPath)
        {
            if (string.IsNullOrEmpty(fromPath)) throw new ArgumentNullException("fromPath");
            if (string.IsNullOrEmpty(toPath)) throw new ArgumentNullException("toPath");
            if (!File.Exists(fromPath))
                throw new FileNotFoundException(fromPath + " does not exist");
            var toDirectory = Path.GetDirectoryName(toPath);
            if (!Directory.Exists(toDirectory))
                throw new DirectoryNotFoundException(toDirectory + " does not exist");
            FromPath = fromPath;
            ToPath = toPath;
            Width = 200;
            Compression = 50; //50%
        }
 
        /// <summary>
        /// Gets or sets from path.
        /// </summary>
        /// <value>From path.</value>
        public string FromPath { get; private set; }
        /// <summary>
        /// Gets or sets to path.
        /// </summary>
        /// <value>To path.</value>
        public string ToPath { get; private set; }
        /// <summary>
        /// Gets or sets the width.
        /// </summary>
        /// <value>The width.</value>
        public int Width { get; set; }
        /// <summary>
        /// Gets or sets the height. 0 indicates height proportional to width.
        /// </summary>
        /// <value>The height.</value>
        public int Height { get; set; }
        private int _compression;
        /// <summary>
        /// Gets or sets the compression. 0 corresponds to the greatest compression, 100 corresponds to the least compression.
        /// </summary>
        /// <value>The compression.</value>
        public int Compression
        {
            get { return _compression; }
            set
            {
                if (value > 100) throw new ArgumentOutOfRangeException("value", "value must be 100 or less");
                if (value < 0) throw new ArgumentOutOfRangeException("value", "value must be 0 or more");
 
                _compression = value;
            }
        }
 
        /// <summary>
        /// Resizes and saves the image.
        /// </summary>
        public void Resize()
        {
            using (Image original = GetBitmapFromFile(FromPath))
            {
                using (Image thumb = CreateThumbnail(original))
                {
                    //jpeg is b96b3cae-...
                    if (original.RawFormat.Guid == ImageFormat.Jpeg.Guid)
                    {
                        SaveAsJpeg(thumb);
                    }
                    else
                    {
                        thumb.Save(ToPath, original.RawFormat);
                    }
                }
            }
        }
 
        /// <summary>
        /// Creates the thumbnail.
        /// </summary>
        /// <param name="original">The original.</param>
        /// <returns></returns>
        private Image CreateThumbnail(Image original)
        {
            //http://west-wind.com/weblog/posts/283.aspx
            Bitmap bmpOut;
            try
            {
                decimal ratio;
                int newWidth;
                int newHeight;
 
                //if the height isn't defined, get one with the right aspect ratio
                if (Height == 0)
                {
                    ratio = (decimal)Width / original.Width;
                    Height = (int)(original.Height * ratio);
                }
 
                //If the image is smaller than a thumbnail just return it
                if (original.Width < Width && original.Height < Height)
                    return new Bitmap(original); //return a copy as we dispose of the original
 
                if (original.Width > original.Height)
                {
                    //wide image
                    ratio = (decimal)Width / original.Width;
                    newWidth = Width;
                    newHeight = (int)(original.Height * ratio);
                }
                else
                {
                    //tall image
                    ratio = (decimal)Height / original.Height;
                    newHeight = Height;
                    newWidth = (int)(original.Width * ratio);
                }
 
                // This code creates cleaner (though bigger) thumbnails and properly
                // and handles GIF files better by generating a white background for
                // transparent images (as opposed to black)
                bmpOut = new Bitmap(newWidth, newHeight);
 
                using (Graphics g = Graphics.FromImage(bmpOut))
                {
                    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    g.FillRectangle(Brushes.White, 0, 0, newWidth, newHeight);
                    g.DrawImage(original, 0, 0, newWidth, newHeight);
                }
            }
            catch
            {
                return null;
            }
            return bmpOut;
        }
 
        private static Bitmap GetBitmapFromFile(string filename)
        {
            return new Bitmap(filename);
        }
 
        private void SaveAsJpeg(Image img)
        {
            //http://msdn.microsoft.com/en-us/library/bb882583.aspx
            //Quality is 0 (most compression) to 100 (least compression)
            long compression = Compression;
 
            var jpgEncoder = ImageCodecInfo.GetImageDecoders()
                .FirstOrDefault(x => x.FormatID == ImageFormat.Jpeg.Guid);
 
            using (var myEncoderParameters = new EncoderParameters(1))
            {
                using (var myEncoderParameter =
                    new EncoderParameter(Encoder.Quality, compression))
                {
                    myEncoderParameters.Param[0] = myEncoderParameter;
                    img.Save(ToPath, jpgEncoder, myEncoderParameters);
                }
            }
        }
    }
}