About the author

Miron Abramson
Me
Software Engineer,
CTO at PixeliT
and .NET addicted for long time.
Open source projects:
MbCompression - Compression library

Recent comments

Authors

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2014

Creative Commons License

Blog Flux Directory
Technology Blogs - Blog Top Sites

Generate thumbnails on the fly - Yet another version

There are many posts how to generate thumbnails using ASP.NET. Some good some less. Be sure to get distance from the versions that use Image.GetThumbnailImage method.

I'm using my own version that going with me from project to project and it is an HttpHandler that registered in the web.config. You can specified maximum height, maximum width, both, specified quality (1-100) and if the image will be cached or not. It is working well with .jpg, .bmp, .png and .gif. The code is too long to write it here, but it is really easy to undestand and really easy to implement and use it.

To use it, add the class to your dll or just drop it in the App_Code folder,register the handler in the web.config as the following:

<add verb="*" path="image.axd" type="Miron.Web.ImageHandler" validate="false"/>

In your site, to generate a thumbnail with size 150X150 in 90% quality (The image will be cached automatically):

<img src="image.axd?src=~/images/photo.jpg&amp;w=150&amp;h=150&amp;q=90">

If you want the image to not be stored in the cache:

<img src="image.axd?src=~/images/photo.jpg&amp;w=150&amp;h=150&amp;q=90&amp;nocache">

 

You can see it in action in the gallery I did to my new nephew Noam: http://mironabramson.com/noam

Hope it will be useful.

ImageHandler.zip (2.85 kb)

Currently rated 4.2 by 6 people

  • Currently 4.166667/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: ASP.NET | C#
Posted by Miron on Sunday, February 08, 2009 7:51 AM
Permalink | Comments (6) | Post RSSRSS comment feed

Resize images 'on the fly' while uploading

Lot of sites (specialy in the web 2.0 times) allows the user to upload images to the site. To save disk space and for visual design reasons, it is better to have the images is small size and specified dimensions. This can be made in two ways. One way is to tell the users to resize the images before uploading them, and the more 'User friendly' way is to let the user upload images with any size and dimensios, and resize them while the uploading.

Here is the code how can it be done:

First we define enum with the resize options:

 public enum ResizeOptions
{
    // Use fixed width & height without keeping the proportions
    ExactWidthAndHeight,

    // Use maximum width (as defined) and keeping the proportions
    MaxWidth,

    // Use maximum height (as defined) and keeping the proportions
    MaxHeight,

    // Use maximum width or height (the biggest) and keeping the proportions
    MaxWidthAndHeight
}

Second, the 'resize' method:

 public static System.Drawing.Bitmap DoResize(System.Drawing.Bitmap originalImg, int widthInPixels, int heightInPixels)
{
       System.Drawing.Bitmap bitmap;
       try
       {
           bitmap = new System.Drawing.Bitmap(widthInPixels, heightInPixels);
           using (System.Drawing.Graphics graphic = System.Drawing.Graphics.FromImage(bitmap))
           {
               // Quality properties
               graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
               graphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
               graphic.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
               graphic.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;

               graphic.DrawImage(originalImg, 0, 0, widthInPixels, heightInPixels);
               return bitmap;
           }
       }
       finally
       {
           if (originalImg != null)
           {
               originalImg.Dispose();
           }
       }
}

Third, the method that calculate the dimensions according to the enum value that passed:

 public static System.Drawing.Bitmap ResizeImage(System.Drawing.Bitmap image, int width, int height, ResizeOptions resizeOptions)
{
    float f_width;
    float f_height;
    float dim;
    switch (resizeOptions)
    {
        case ResizeOptions.ExactWidthAndHeight:
            return DoResize(image, width, height);

        case ResizeOptions.MaxHeight:
            f_width = image.Width;
            f_height = image.Height;

            if (f_height <= height)
                return DoResize(image, (int)f_width, (int)f_height);

            dim = f_width / f_height;
            width = (int)((float)(height) * dim);
            return DoResize(image, width, height);

        case ResizeOptions.MaxWidth:
            f_width = image.Width;
            f_height = image.Height;

            if (f_width <= width)
                return DoResize(image, (int)f_width, (int)f_height);

            dim = f_width / f_height;
            height = (int)((float)(width) / dim);
            return DoResize(image, width, height);

        case ResizeOptions.MaxWidthAndHeight:
            int tmpHeight = height;
            int tmpWidth = width;
            f_width = image.Width;
            f_height = image.Height;

            if (f_width <= width && f_height <= height)
                return DoResize(image, (int)f_width, (int)f_height);

            dim = f_width / f_height;

            // Check if the width is ok
            if (f_width < width)
                width = (int)f_width;
            height = (int)((float)(width) / dim);
            // The width is too width
            if (height > tmpHeight)
            {
                if (f_height < tmpHeight)
                    height = (int)f_height;
                else
                    height = tmpHeight;
                width = (int)((float)(height) * dim);
            }
            return DoResize(image, width, height);
        default:
            return image;
    }
}

Last thing is to connect it all to the uploading event: (Our uploading control called 'fuPhoto' (Normal 'FileUpload' control))

 public bool UploadFile()
{
    // Make some validatins check (control have file or extension check...)

    int width = 300;
    int height = 300;

    // Do the resize, and save the file with desired name
    using( System.Drawing.Bitmap img = ResizeImage(new System.Drawing.Bitmap(fuPhoto.PostedFile.InputStream), width, height, ResizeOptions.MaxWidthAndHeight))
    {
        string destination = Server.MapPath("~") + Path.GetFileName(FileUpload1.FileName);
        switch (Path.GetExtension(fuPhoto.FileName).ToLower())
        {
            case ".gif":
                img.Save(destination, System.Drawing.Imaging.ImageFormat.Gif);
                break;
            case ".jpg":
            default:
                img.Save(destination, System.Drawing.Imaging.ImageFormat.Jpeg);
                break;
        }
    }
}

Update:

Some readers asked my about how can this code be used to resize the uploaded image and than save it in to the DB and not to the disk. To save the image to the DB we need to convert it into byte[] (That is how it needs to be sent to the Store Procedre). This can be done in some way. one way is:

 public static byte[] ImageToArray(Bitmap image, ImageFormat format)
 {
       using(MemoryStream mem = new MemoryStream())
       {
           mem.Position = 0;
           image.Save(mem, format);
           return mem.ToArray();
       }
  }

 Upload the file using the method 'ResizeImage', than convert the returned Bitmap into byte[] using this method, and send it to your Store Procedure.

done 

Currently rated 4.5 by 15 people

  • Currently 4.466667/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: ASP.NET | C#
Posted by Miron on Sunday, October 28, 2007 1:24 AM
Permalink | Comments (29) | Post RSSRSS comment feed