Monday, January 21, 2008

How To: SlideShowPro administration in ASP.NET: Image Resizing

For anyone looking to create a simple, yet elegant media gallery, SlideShowPro is hard to beat. It's a great bang for the buck and is fairly simple to integrate into an existing website as it reads data directly from a simple xml file.

This is the first part in a series of posts detailing how to create ASP.Net pages for managing a SlideShowPro gallery. Any gallery "control panel" needs the ability to upload and resize media, so this is where we'll start.

I'm going to show you a simple method of resizing an image in C#. These basic concepts are what I used in building the more advanced, but reusable Imaging class. I've decided not to include the detailed steps in creating the class in this article because it's just too much code and is much easier to follow by looking at the project in Visual Studio.

I know some of you are not interested in the code, so go ahead and just download the assembly and sample pages here:.
Source, compiled assembly, and sample pages

Let's start by importing a few classes:

using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
You'll be able to paste this code into a page and start using it right away.
private void resize()
        //Open the image to resize
        System.Drawing.Image workingFile = System.Drawing.Image.FromFile("C:\\image-to-resize.tmp");

        //Set some maximum dimensions
        double maxHeight = 400;
        double maxWidth = 400;

        //Determine whether this image is portrait or landscape
        double widthRatio; double heightRatio; double multiplier;

        heightRatio = maxHeight / workingFile.Height;
        widthRatio = maxWidth / workingFile.Width;

        if (widthRatio < heightRatio) // portrait
            multiplier = widthRatio;
        else //landscape
            multiplier = heightRatio;

        // Calculate the proportionate size of the scaled image
        int width = (int)Math.Ceiling(workingFile.Width * multiplier);
        int height = (int)Math.Ceiling(workingFile.Height * multiplier);

        //Create an empty bitmap and graphics object using our new dimensions
        Bitmap workingBitmap = new Bitmap(width, height, workingFile.PixelFormat);
        Graphics workingGraphics = Graphics.FromImage(workingBitmap);

        //Set some quality parameters
        workingGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
        workingGraphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

        //Now draw the image onto our new graphics surface
        workingGraphics.DrawImage(workingFile, 0, 0, workingBitmap.Width, workingBitmap.Height);

        //Save the scaled image to a new location
        workingBitmap.Save("C:\\resized-image.jpg", imageCodec(), imageEncoder(90));

        //Dispose of our graphics objects so no memory is wasted

    //You'll need these 2 private methods in order to encode the jpg with a respectable quality level
    private EncoderParameters imageEncoder(long quality)
        EncoderParameters encoderParams = new EncoderParameters(1);
        EncoderParameter qualParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
        encoderParams.Param[0] = qualParam;
        return encoderParams;

    private ImageCodecInfo imageCodec()
        ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();
        ImageCodecInfo codec = null;
        for (int x = 0; x < encoders.Length; x++)
            if (encoders[x].FormatDescription.ToUpper() == "JPEG")
                codec = encoders[x];
        return codec;
Here's a simple usage example for those downloading the source:
//Add a reference to the assembly and add a using statement:
using BlueEnum.Utility;

//Create an instance of our imaging component.
Imaging canvas = new Imaging();
//Let's open the temp file in order to resize it.
//Now lets resize to more web friendly dimensions.
canvas.Scale(400, 350); //These are maximums. Resizing will be proportional.

//**Optional Watermark**
string watermarkLocation = "C:\\watermark.png";
canvas.Watermark(watermarkLocation, Imaging.WaterMarkPosition.LowerRight, 5);

//**Optional Remove Source File**
canvas.RemoveSourceOnSave = true;

//We're now ready to save the resized file
canvas.Save("C:\\destination.jpg", 90); //The second parameter is jpg compression.
//Let's dump any resources used by the Imaging class
canvas = null;
Source, compiled assembly, and sample pages

Wednesday, January 16, 2008

Dreamweaver, not so dreamy anymore?

Am I the only person that is really disappointed with the current version of Dreamweaver? As an ASP.Net developer I can't help but feel like we have just been left out of the party. Where is the quality Master Page and Theme support? Why aren't any of the new server controls supported? Have you really been spending a development life-cycle integrating that Spry Framework? Is it just me or does it seem like Adobe is turning the cold shoulder to ASP? I guess I could use Expression Web, but Dreamweaver still has a more intuitive design UI for me....Adobe, give me my Master Pages!

Tuesday, January 15, 2008

Let's Get Started

It's hard to believe that my dream as a youngster was to be an illustrator in the comic book industry. So with a background in fine art and graphic design, how did I end up as a Lead Dev on an ASP.NET web team? Well, I'm still not sure, but it's been a fun ride getting here and now I'd like to share some of the cool techniques I've learned along the way. It's a known dilemna that programmers aren't typically premier designers....and designers aren't normally too hot at programming. I'm hoping to bring some articles that will bridge that gap for some of you in the form of tutorials and examples. Keep checking back as I've got some cool ideas for a series of articles to help you bring some flashy, yet solid functionality to your web apps.