Resize image to be web friendly

There’s already a post about this subject on the blog but it is in italian, I want to propose it again because the task of resizing and slim the pictures we got (for facebook, for our blog) is a common task we are all used to. Here’s the code and a small console app you can use for this purpose, it is very easy to use: set the path of the input folder, the desired quality and resolution for the output and wait for the app to convert the images. Below the code and a couple of screenshoots of the app:

class Program
{
    static void Main(string[] args)
    {
        Console.Write(@"Select input folder (ie: c:\images):");
        string folder = Console.ReadLine();
        Console.Write("Choose image height(ie: 1024) :");
        int width = Convert.ToInt32(Console.ReadLine());
        Console.Write("Choose image width (ie: 768) :");
        int height = Convert.ToInt32(Console.ReadLine());
        Console.Write("Choose quality (0 - 100):");
        int quality = Convert.ToInt32(Console.ReadLine());
        string newFolder = folder + "_resized";
        Console.Write("Output folder will be: {0}", newFolder);
        Console.Write("Please wait until the conversion is complete.");
        List<string> files = Directory.GetFiles(folder).ToList();
        Directory.CreateDirectory(newFolder);
        foreach (string file in files)
        {
            ImageUtilities.ResizeImage(file, (newFolder + "\\" + Path.GetFileName(file)), width, height, true, quality);
        }
        Console.WriteLine("Done!");
        Console.WriteLine("Press any key to exit");
        Console.ReadLine();
    }

}
/// <summary>
/// Provides various image untilities, such as high quality resizing and the ability to save a JPEG.
/// </summary>
public static class ImageUtilities
{
    /// <summary>
    /// A quick lookup for getting image encoders
    /// </summary>
    private static Dictionary<string, ImageCodecInfo> encoders = null;

    /// <summary>
    /// A quick lookup for getting image encoders
    /// </summary>
    public static Dictionary<string, ImageCodecInfo> Encoders
    {
        //get accessor that creates the dictionary on demandd
        get
        {
            //if the quick lookup isn't initialised, initialise it
            if (encoders == null)
            {
                encoders = new Dictionary<string, ImageCodecInfo>();
            }

            //if there are no codecs, try loading them
            if (encoders.Count == 0)
            {
                //get all the codecs
                foreach (ImageCodecInfo codec in ImageCodecInfo.GetImageEncoders())
                {
                    //add each codec to the quick lookup
                    encoders.Add(codec.MimeType.ToLower(), codec);
                }
            }

            //return the lookup
            return encoders;
        }
    }

    public static void ResizeImage(string OriginalFile, string NewFile, int NewWidth, int MaxHeight, bool OnlyResizeIfWider, int quality)
    {
        System.Drawing.Image FullsizeImage = System.Drawing.Image.FromFile(OriginalFile);

        // Prevent using images internal thumbnail
        FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
        FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);

        if (OnlyResizeIfWider)
        {
            if (FullsizeImage.Width <= NewWidth)
            {
                NewWidth = FullsizeImage.Width;
            }
        }

        int NewHeight = FullsizeImage.Height * NewWidth / FullsizeImage.Width;
        if (NewHeight > MaxHeight)
        {
            // Resize with height instead
            NewWidth = FullsizeImage.Width * MaxHeight / FullsizeImage.Height;
            NewHeight = MaxHeight;
        }

        System.Drawing.Image NewImage = FullsizeImage.GetThumbnailImage(NewWidth, NewHeight, null, IntPtr.Zero);

        // Clear handle to original file so that we can overwrite it if necessary
        FullsizeImage.Dispose();

        // Save resized picture
        //NewImage.Save(NewFile);
        SaveJpeg(NewFile, NewImage, quality);
    }

    /// <summary> 
    /// Saves an image as a jpeg image, with the given quality 
    /// </summary> 
    /// <param name="path">Path to which the image would be saved.</param> 
    /// <param name="quality">An integer from 0 to 100, with 100 being the 
    /// highest quality</param> 
    /// <exception cref="ArgumentOutOfRangeException">
    /// An invalid value was entered for image quality.
    /// </exception>
    public static void SaveJpeg(string path, Image image, int quality)
    {
        //ensure the quality is within the correct range
        if ((quality < 0) || (quality > 100))
        {
            //create the error message
            string error = string.Format("Jpeg image quality must be between 0 and 100, with 100 being the highest quality.  A value of {0} was specified.", quality);
            //throw a helpful exception
            throw new ArgumentOutOfRangeException(error);
        }

        //create an encoder parameter for the image quality
        EncoderParameter qualityParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
        //get the jpeg codec
        ImageCodecInfo jpegCodec = GetEncoderInfo("image/jpeg");

        //create a collection of all parameters that we will pass to the encoder
        EncoderParameters encoderParams = new EncoderParameters(1);
        //set the quality parameter for the codec
        encoderParams.Param[0] = qualityParam;
        //save the image using the codec and the parameters
        image.Save(path, jpegCodec, encoderParams);
    }

    /// <summary> 
    /// Returns the image codec with the given mime type 
    /// </summary> 
    public static ImageCodecInfo GetEncoderInfo(string mimeType)
    {
        //do a case insensitive look at the mime type
        mimeType = mimeType.ToLower();

        //the codec to return, default to null
        ImageCodecInfo foundCodec = null;

        //if we have the encoder, get it to return
        if (Encoders.ContainsKey(mimeType))
        {
            //pull the codec from the lookup
            foundCodec = Encoders[mimeType];
        }

        return foundCodec;
    }
}

image image

Here’s the console app.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s