C++ C++ C# C# ASP.NET Security ASP.NET Security ASM ASM Скачать Скачать Поиск Поиск Хостинг Хостинг  
  Программа для работы с LPT портом...
Язык: .NET — ©Alexey...
  "ASP.NET Atlas" – AJAX в исполнении Micro...
Язык: .NET — ©legigor@mail.ru...
  "Невытесняющая" Многопоточность...
Язык: C/C++ — ©...
  Update World C++: Сборник GPL QT исходников
  Весь сайт целиком можно загрузить по ссылкам из раздела Скачать
Letyshops [lifetime]

 Quick Snip - Lightweight image resizer / Graphics / C#

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 ;)




Letyshops [lifetime]