Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Quick Snip - Lightweight image resizer

0.00/5 (No votes)
8 May 2005 1  
Quick Snip is an incredibly lightweight application to make "web sized" pictures out of large images

Sample Image - screenshot.png

Introduction

Quick Snip is an incredibly lightweight application to make "web sized" pictures out of large images. I often want to take pictures with a digital camera and just want a 600 max width picture that I can easily email to my friends. Common image software like GIMP and Photoshop have too much overhead - opening, picking settings and choosing directories over and over again is annoying. Quick Snip is accessed via the "Send to" menu and drops a JPG in the same directory with the name + "_resized.jpg". One step, no fuss, no annoyance.

Background

This program gives a very quick introduction on how to take an image and resize it. I use a more robust version of this embedded into my website to automatically resize images for gallery collections. It also touches on how to do basic console program operations like read/write to console and pass in parameters. Reading and understanding this article should hopefully be very easy, and greatly expand your programming options.

Using the code

Important Notes

If you want to create a console application from scratch, you need to manually add a �.NET reference� to System.Drawing. (References -> Add Reference -> System.drawing | OK).

In order to register a program to be used in �Send to�, you need to add a shortcut to the Send to directory. On my computer (Windows 2003), the directory is located at \Documents and Settings\User\SendTo.

Now on to the code!

When a file is selected and the �send to� command is used, each filename is passed in as a subsequent command line parameter. We can easily iterate through each of the files.

foreach (string FileName in args)
{
    // quickly slap "_resized.jpg" at the end.

    string NewFileName = FileName.Substring(0, 
                         (FileName.Length -4)) + "_resized.jpg"
            
    ResizeImage(600,600, FileName, NewFileName);                
}

Next we need a piece of code to handle the image resizing:

public static void ResizeImage(int MaxWidth, 
          int MaxHeight, string FileName, string NewFileName)
{
    // load up the image, figure out a "best fit" resize,

    // and then save that new image

    Bitmap OriginalBmp = 
           (System.Drawing.Bitmap)Image.FromFile(FileName).Clone();
    Size ResizedDimensions = 
         GetDimensions(MaxWidth, MaxHeight, ref OriginalBmp);
    Bitmap NewBmp = new Bitmap(OriginalBmp, ResizedDimensions);
        
    NewBmp.Save(NewFileName, System.Drawing.Imaging.ImageFormat.Jpeg);
}

The actual algorithm to figure out the optimal size is handled by a function called GetDimensions. GetDimensions is a very simple function to return a reasonable set of dimensions for the resized image.

public static Size GetDimensions(int MaxWidth, int MaxHeight, ref Bitmap Bmp)
{
    int Width;
    int Height;
    float Multiplier;

    Height = Bmp.Height;
    Width = Bmp.Width;

    // this means you want to shrink an image that is already shrunken!

    if (Height <= MaxHeight && Width <= MaxWidth)
        return new Size(Width, Height);

    // check to see if we can shrink it width first

    Multiplier = (float)((float)MaxWidth / (float)Width);
    if ((Height * Multiplier)<= MaxHeight)
    {
        Height = (int)(Height * Multiplier);
        return new Size(MaxWidth, Height);
    }

    // if we can't get our max width, then use the max height

    Multiplier = (float)MaxHeight / (float)Height;
    Width = (int)(Width * Multiplier);
    return new Size(Width, MaxHeight);
}

That's it!

Complete Code

using System;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace QuickSnip
{
    class Class1
    {
        
        [STAThread]
        static void Main(string[] args)
        {
            // when you use send to it will pass each file

            // as it's own string in args

            foreach (string FileName in args)
            {
                try
                {
                    // quickly slap "_resized.jpg" at the end.

                    string NewFileName = FileName.Substring(0, 
                           (FileName.Length -4)) + "_resized.jpg";

                    // nice when you have multiple images

                    Console.WriteLine(FileName);
                    Console.WriteLine(NewFileName);

                    // call our thumbnail function

                    ResizeImage(600,600, FileName, NewFileName);
                }
                catch (System.Exception ex)
                {
                    // UH OH!!!

                    Console.Write(ex.Message);
                    Console.ReadLine();
                }
            }
        }
    
        /// <SUMMARY>

        /// This function takes a max width/height

        /// and makes a new file based on it

        /// </SUMMARY>

        /// <PARAM name="MaxWidth">Max width of the new image</PARAM>

        /// <PARAM name="MaxHeight">Max Height of the new image</PARAM>

        /// <PARAM name="FileName">Original file name</PARAM>

        /// <PARAM name="NewFileName">new file name</PARAM>

        public static void ResizeImage(int MaxWidth, int MaxHeight, 
                               string FileName, string NewFileName)
        {
            // load up the image, figure out a "best fit"

            // resize, and then save that new image

            Bitmap OriginalBmp = 
               (System.Drawing.Bitmap)Image.FromFile(FileName).Clone();
            Size ResizedDimensions = 
               GetDimensions(MaxWidth, MaxHeight, ref OriginalBmp);
            Bitmap NewBmp = new Bitmap(OriginalBmp, ResizedDimensions);
            
            NewBmp.Save(NewFileName, System.Drawing.Imaging.ImageFormat.Jpeg);
        }

        /// <SUMMARY>

        /// this function aims to give you a best fit

        /// for a resize. It assumes width is more important 

        /// then height. If an image is already smaller

        /// then max dimensions it will not resize it.

        /// </SUMMARY>

        /// <PARAM name="MaxWidth">max width of the new image</PARAM>

        /// <PARAM name="MaxHeight">max height of the new image</PARAM>

        /// <PARAM name="Bmp">BMP of the current image,

        ///              passing by ref so fast</PARAM>

        /// <RETURNS></RETURNS>

        public static Size GetDimensions(int MaxWidth, 
                           int MaxHeight, ref Bitmap Bmp)
        {
            int Width;
            int Height;
            float Multiplier;

            Height = Bmp.Height;
            Width = Bmp.Width;

            // this means you want to shrink

            // an image that is already shrunken!

            if (Height <= MaxHeight && Width <= MaxWidth)
                return new Size(Width, Height);

            // check to see if we can shrink it width first

            Multiplier = (float)((float)MaxWidth / (float)Width);
            if ((Height * Multiplier)<= MaxHeight)
            {
                Height = (int)(Height * Multiplier);
                return new Size(MaxWidth, Height);
            }

            // if we can't get our max width, then use the max height

            Multiplier = (float)MaxHeight / (float)Height;
            Width = (int)(Width * Multiplier);
            return new Size(Width, MaxHeight);
        }
    }
}

Points of Interest

I have a number of programs I have written that end up doing image resizing and minor image manipulation. My personal website uses a simple directory scanner to look for new collections of images. When it finds them it automatically creates thumbnails, and web sized versions. I have another program that finds images on my computer and on a timer randomly creates a copy, re-sizes and re-sets my wallpaper. Overall I have found minor image manipulation easy to write with powerful results.

I hope people find my first article useful, and I will begin to post some of my more interesting code.

History

No history yet ;)

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here